home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / Tool Chest / Development Platforms / AppsToGo / AppsToGo.src / DTS.Lib / Window2.c < prev   
Encoding:
C/C++ Source or Header  |  1993-06-18  |  79.4 KB  |  3,185 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:     DTS.Lib
  5. ** File:        window2.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1993 Apple Computer, Inc.
  9. ** All rights reserved.
  10. */
  11.  
  12. /* You may incorporate this sample code into your applications without
  13. ** restriction, though the sample code has been provided "AS IS" and the
  14. ** responsibility for its operation is 100% yours.  However, what you are
  15. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  16. ** after having made changes. If you're going to re-distribute the source,
  17. ** we require that you make it clear in the source that the code was
  18. ** descended from Apple Sample Code, but that you've made changes. */
  19.  
  20.  
  21.  
  22. /*****************************************************************************/
  23.  
  24.  
  25.  
  26. #include "DTS.Lib2.h"
  27. #include "DTS.Lib.protos.h"
  28.  
  29. #ifndef __BALLOONS__
  30. #include <Balloons.h>
  31. #endif
  32.  
  33. #ifndef __DESK__
  34. #include <Desk.h>
  35. #endif
  36.  
  37. #ifndef __ERRORS__
  38. #include <Errors.h>
  39. #endif
  40.  
  41. #ifndef __FONTS__
  42. #include <Fonts.h>
  43. #endif
  44.  
  45. #ifndef __MOVIES__
  46. #include <Movies.h>
  47. #endif
  48.  
  49. #ifndef __RESOURCES__
  50. #include <Resources.h>
  51. #endif
  52.  
  53. #ifndef __SCRIPT__
  54. #include <Script.h>
  55. #endif
  56.  
  57. #ifndef __STDDEF__
  58. #include <StdDef.h>
  59. #endif
  60.  
  61. #ifndef THINK_C
  62. #ifndef __SYSEQU__
  63. #include <SysEqu.h>
  64. #endif
  65. #endif
  66.  
  67. #ifndef __TOOLUTILS__
  68. #include <ToolUtils.h>
  69. #endif
  70.  
  71. #ifndef __UTILITIES__
  72. #include "Utilities.h"
  73. #endif
  74.  
  75.  
  76.  
  77. /*****************************************************************************/
  78.  
  79.  
  80. typedef struct {
  81.     Rect            contrlRect;
  82.     short            contrlValue;
  83.     unsigned char    contrlVis;
  84.     short            contrlMax;
  85.     short            contrlMin;
  86.     long            contrlRfCon;
  87.     Str255            contrlTitle;
  88. } CtlTemplate;
  89.  
  90. extern short    gTECtl;
  91. extern short    gListCtl;
  92. extern short    gCIconCtl;
  93. extern short    gPICTCtl;
  94. extern short    gDataCtl;
  95.  
  96. extern short            gPrintPage;                    /* Non-zero means we are printing. */
  97. extern short            gMinVersion, gMaxVersion;
  98. extern Boolean            gInBackground;
  99. extern WindowTemplate    gWindowTemplate, gOpenedWindowTemplate;
  100.  
  101. extern short            gTypeListLen;
  102. extern SFTypeList        gTypeList;
  103. extern long                gAppWindowAttr;
  104. extern OSType            gAppWindowType;
  105. extern Boolean            gNoDefaultDocument;
  106.  
  107. OSType                *gTypeListPtr = gTypeList;
  108. short                gBeginUpdateNested;
  109. TreeObjHndl            gWindowFormats;
  110. OSErr                gDialogErr;
  111.  
  112. static RgnHandle    gKeepUpdateRgn;
  113. static WindowPtr    gOldPort;
  114.  
  115. RgnHandle    gCursorRgn;
  116.     /* The current cursor region.  The initial cursor region is an empty
  117.     ** region, which will cause WaitNextEvent to generate a mouse-moved
  118.     ** event, which will cause us to set the cursor for the first time. */
  119.  
  120. static Cursor    gCursor;
  121. CursPtr            gCursorPtr;
  122.     /* The current cursor that applies to gCursorRgn.  These values
  123.     ** are here to shorten the re-processing time for determining the
  124.     ** correct cursor after an event.  This is specifically so that characters
  125.     ** can be typed into the TextEdit control faster.  If we spend a great
  126.     ** deal of time per-event recalculating the cursor region, text entry for
  127.     ** the TextEdit control slows down considerably.  If you want to override
  128.     ** the time savings because you are changing the cursor directly, either
  129.     ** set gCursorPtr to nil, or call DoSetCursor to set the cursor.
  130.     ** DoSetCursor simply sets gCursorPtr to nil, as well as setting
  131.     ** the cursor. */
  132.  
  133. static Rect                    OldLocWindow(WindowPtr window, WindowPtr relatedWindow, Rect sizeInfo);
  134. static PositionWndProcPtr    gOldLocProc;
  135.  
  136.  
  137.  
  138. /*****************************************************************************/
  139. /*****************************************************************************/
  140.  
  141.  
  142.  
  143. /* This function creates a new application window.  An application window
  144. ** contains a document which is referenced by a handle in the refCon field. */
  145.  
  146. #pragma segment Window
  147. OSErr    DoNewWindow(FileRecHndl frHndl, WindowPtr *retWindow, WindowPtr relatedWindow, WindowPtr behind)
  148. {
  149.     WindowPtr            oldPort, window;
  150.     FileRecHndl            ffrHndl;
  151.     ControlHandle        ctl;
  152.     Rect                ctlRect, contRect, userState, sizeInfo, rct, rct2, msrct, oldPlaceRct;
  153.     short                h, v, hDocSize, vDocSize;
  154.     long                wkind, wwkind, attributes;
  155.     OSErr                err;
  156.     PositionWndProcPtr    proc;
  157.     GDHandle            device;
  158.     PixMapHandle        pmap;
  159.  
  160.     if (!frHndl) return(noErr);
  161.     attributes = (*frHndl)->fileState.attributes;
  162.  
  163.     err = noErr;
  164.     GetPort(&oldPort);
  165.  
  166.     proc = (*frHndl)->fileState.getDocWindow;
  167.  
  168.     if (attributes & kwStaggerWindow) proc = StaggerWindow;
  169.     if (attributes & kwCenterWindow)  proc = CenterWindow;
  170.  
  171.     gOldLocProc = proc;
  172.     if (attributes & kwOpenAtOldLoc)  proc = OldLocWindow;            /* Try to open window at old location. */
  173.  
  174.     SetRect(&sizeInfo, 0, 0, 0, 0);
  175.     if ((proc == StaggerWindow) || (proc == OldLocWindow)) {
  176.         if (hDocSize = (*frHndl)->d.doc.fhInfo.hDocSize) {
  177.             hDocSize += (*frHndl)->fileState.leftSidebar;
  178.             if (attributes & kwHScroll) hDocSize += 15;
  179.         }
  180.         if (vDocSize = (*frHndl)->d.doc.fhInfo.vDocSize) {
  181.             vDocSize += (*frHndl)->fileState.topSidebar;
  182.             if (attributes & kwVScroll) vDocSize += 15;
  183.         }
  184.         SetRect(&sizeInfo, hDocSize, vDocSize, hDocSize, vDocSize);
  185.     }
  186.  
  187.     wkind = (attributes & (kwIsPalette | kwIsModalDialog));
  188.     if (behind) {
  189.         for (;;) {
  190.             if (!(behind = GetNextWindow(behind, 0))) break;
  191.                 /* break if behind all windows.  behind is nil, so that's what we have. */
  192.             if (!((WindowPeek)behind)->visible) continue;
  193.             ffrHndl = (FileRecHndl)GetWRefCon(behind);
  194.             wwkind  = ((*ffrHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog));
  195.             if (wkind >= wwkind) {
  196.                 for (;;) {
  197.                     behind = GetPreviousWindow(behind);
  198.                     if (behind == (WindowPtr)-1)       break;
  199.                     if (((WindowPeek)behind)->visible) break;
  200.                 }
  201.                 break;
  202.             }
  203.         }
  204.     }
  205.  
  206.     oldPlaceRct = SetWindowPlacementRect(nil);
  207.     if (EmptyRect(&oldPlaceRct)) {
  208.  
  209.         if (attributes & kwSameMonitor)
  210.             for (relatedWindow = nil; relatedWindow = GetNextWindow(relatedWindow, (*frHndl)->fileState.sfType);)
  211.                 if (((WindowPeek)relatedWindow)->visible) break;
  212.  
  213.         if ((!(attributes & kwSameMonitor)) || (!relatedWindow)) {
  214.             if (attributes & (kwColorMonitor | kwSecondaryMonitor)) {
  215.     
  216.                 if (gQDVersion > kQDOriginal) {
  217.                     rct = msrct = GetMainScreenRect();
  218.                     for (device = GetDeviceList(); device; device = GetNextDevice(device)) {
  219.                         rct2 = (*device)->gdRect;
  220.                         if (TestDeviceAttribute(device, screenDevice) &&
  221.                             TestDeviceAttribute(device, screenActive)
  222.                         ) {
  223.                             pmap = (*device)->gdPMap;
  224.                             if (attributes & kwColorMonitor) {
  225.                                 if ((*pmap)->pixelSize > 1) {
  226.                                     rct = rct2;
  227.                                     if (!(rct.top | rct.left)) break;
  228.                                 }
  229.                             }
  230.                             else {
  231.                                 if (!EqualRect(&rct2, &msrct)) {
  232.                                     rct = rct2;
  233.                                     break;
  234.                                 }
  235.                             }
  236.                         }
  237.                     }
  238.                     if (EqualRect(&rct, &msrct))
  239.                         rct.top += GetMBarHeight();
  240.                     SetWindowPlacementRect(&rct);
  241.                 }
  242.             }
  243.         }
  244.     }
  245.  
  246.     window = GetSomeKindOfWindow(proc, (*frHndl)->fileState.windowID, nil, false, relatedWindow,
  247.                                  behind, true, sizeInfo, (long)frHndl);
  248.  
  249.     SetWindowPlacementRect(&oldPlaceRct);
  250.  
  251.     if (window) {
  252.         SetPort(window);
  253.         NewWindowTitle(window, nil);
  254.  
  255.         (*frHndl)->fileState.window = window;
  256.  
  257.         (*frHndl)->fileState.hArrowVal = 16;    /* Default arrow value is 16. */
  258.         (*frHndl)->fileState.vArrowVal = 16;
  259.  
  260.         if (!(*frHndl)->d.doc.fhInfo.hDocSize) {
  261.             h  = gOpenedWindowTemplate.boundsRect.right - gOpenedWindowTemplate.boundsRect.left;
  262.             h -= (*frHndl)->fileState.leftSidebar;    /* Default document size is */
  263.             if (attributes & kwVScroll)                /* content less leftSidebar */
  264.                 h -= 15;                            /* value less scrollbars.   */
  265.             (*frHndl)->d.doc.fhInfo.hDocSize = h;
  266.         }
  267.         if (!(*frHndl)->d.doc.fhInfo.vDocSize) {
  268.             v  = gOpenedWindowTemplate.boundsRect.bottom - gOpenedWindowTemplate.boundsRect.top;
  269.             v  = window->portRect.bottom;
  270.             v -= (*frHndl)->fileState.topSidebar;    /* We don't have to initialize the page */
  271.             if (attributes & kwHScroll)                /* values since the scrollbars won't be */
  272.                 v -= 15;                            /* active until the window is resized   */
  273.             (*frHndl)->d.doc.fhInfo.vDocSize = v;    /* or these values are set elsewhere.   */
  274.         }
  275.  
  276.         if (attributes & kwHScroll) {        /* Caller wants a horizontal scrollbar... */
  277.             ctlRect = window->portRect;
  278.             ctlRect.left += (*frHndl)->fileState.leftSidebar;
  279.             ctlRect.left += (*frHndl)->fileState.hScrollIndent;
  280.             --ctlRect.left;
  281.             ++ctlRect.right;
  282.             ctlRect.top = ++ctlRect.bottom - 16;
  283.             if (attributes & (kwHScrollLessGrow - kwHScroll +  kwGrowIcon))
  284.                 ctlRect.right -= 15;
  285.             OffsetRect(&ctlRect, 0, -16384);
  286.             ctl = NewControl(window, &ctlRect, "\p", true, 0, 0, 0, scrollBarProc, 0L);
  287.             if (ctl)
  288.                 (*frHndl)->fileState.hScroll = ctl;
  289.             else
  290.                 err = memFullErr;
  291.         }
  292.  
  293.         if (!err) {
  294.             if (attributes & kwVScroll) {        /* Caller wants a vertical scrollbar... */
  295.                 ctlRect = window->portRect;
  296.                 ctlRect.top += (*frHndl)->fileState.topSidebar;
  297.                 ctlRect.top += (*frHndl)->fileState.vScrollIndent;
  298.                 --ctlRect.top;
  299.                 ++ctlRect.bottom;
  300.                 ctlRect.left = ++ctlRect.right - 16;
  301.                 if (attributes & (kwVScrollLessGrow - kwVScroll +  kwGrowIcon))
  302.                     ctlRect.bottom -= 15;
  303.                 OffsetRect(&ctlRect, 0, -16384);
  304.                 ctl = NewControl(window, &ctlRect, "\p", true, 0, 0, 0, scrollBarProc, 0L);
  305.                 if (ctl)
  306.                     (*frHndl)->fileState.vScroll = ctl;
  307.                 else
  308.                     err = memFullErr;
  309.             }
  310.         }
  311.  
  312.         if (!err) {
  313.             err = DoInitContent(frHndl, window);
  314.             if (!err) {
  315.                 contRect   = GetWindowContentRect(window);
  316.                 if (((WindowPeek)window)->spareFlag)
  317.                     userState = mDerefWStateData(window)->userState;
  318.                         /* Cache this.  ShowWindow offscreen messes it up.  We want to keep
  319.                         ** whatever it is because some other function may be tweeking stdState
  320.                         ** and userState so that window position and zoom state can be saved
  321.                         ** along with a document. */
  322.  
  323.                 MoveWindow(window, 16384, 16384, false);
  324.                     /* When an invisible window is added, it isn't the frontmost window.
  325.                     ** This causes a problem when we make it visible.  By moving it
  326.                     ** offscreen, we can make it visible without the user seeing that it
  327.                     ** isn't the top window. */
  328.  
  329.                 if (gPrintPage) {
  330.                     ShowWindow(window);                            /* Window now visible. */
  331.                     MoveWindow(window, 16384, 16384, true);        /* Window now on top.  */
  332.                 }    /* If we are printing, we want to leave the window offscreen, since we
  333.                     ** don't want it seen.  We do need a visible window when printing so
  334.                     ** PrintMonitor can get the document name. */
  335.  
  336.                 if (!gPrintPage) {
  337.                     if (attributes & kwVisible)
  338.                         ShowHide(window, true);
  339.                     CleanSendBehind(window, behind);
  340.                     MoveWindow(window, contRect.left, contRect.top, false);
  341.                 }
  342.  
  343.                 if (((WindowPeek)window)->spareFlag)
  344.                     mDerefWStateData(window)->userState = userState;
  345.                         /* The ShowWindow metrics we did cause the userState to change.  Put it
  346.                         ** back the way it was before we started messing around with the window. */
  347.  
  348.                 AdjustScrollBars(window);
  349.             }
  350.         }
  351.         if (err) {
  352.             DisposeAnyWindow(window);
  353.             (*frHndl)->fileState.window = window = nil;
  354.         }
  355.     }
  356.     else err = memFullErr;
  357.  
  358.     SetPort(oldPort);
  359.     if (retWindow)
  360.         *retWindow = window;
  361.  
  362.     return(err);
  363. }
  364.  
  365.  
  366.  
  367. /*****************************************************************************/
  368.  
  369.  
  370.  
  371. /* This function updates the window title to reflect the new document name.
  372. ** The new document name is stored in the fileState portion of the document.
  373. ** This is automatically set to 'Untitled # N' for new documents, and is
  374. ** updated when a user does a save-as.  If the window that is being opened
  375. ** should have the resource name, then set the new document name to an
  376. ** empty string prior to calling DoNewWindow.  When this is called by
  377. ** DoNewWindow, the SetWTitle will be suppressed. */
  378.  
  379. #pragma segment Window
  380. void    NewWindowTitle(WindowPtr window, StringPtr altTitle)
  381. {
  382.     FileRecHndl    frHndl;
  383.     Str255        wTitle;
  384.  
  385.     if (window) {
  386.         if (altTitle) {
  387.             pcpy(wTitle, altTitle);
  388.             SetWTitle(window, wTitle);
  389.         }
  390.         else if (frHndl = (FileRecHndl)GetWRefCon(window)) {
  391.             pcpy(wTitle, (*frHndl)->fileState.fss.name);
  392.             if (*wTitle)
  393.                 SetWTitle(window, wTitle);
  394.             else {
  395.                 if ((*frHndl)->fileState.refNum == kInvalRefNum) {
  396.                     GetWTitle(window, wTitle);
  397.                     if (*wTitle > 63) *wTitle = 63;
  398.                     pcpy((*frHndl)->fileState.fss.name, wTitle);
  399.                 }
  400.             }
  401.         }
  402.     }
  403. }
  404.  
  405.  
  406.  
  407. /*****************************************************************************/
  408.  
  409.  
  410.  
  411. /* Close all the windows.  This is called prior to quitting the application.
  412. ** This function returns true if all windows were closed.  The user may decide
  413. ** to abort a save, thus stopping the closing of the windows.  If the user
  414. ** does this, false will be returned, indicating that all windows were not
  415. ** closed after all. */
  416.  
  417. #pragma segment Window
  418. Boolean    DisposeAllWindows(void)
  419. {
  420.     WindowPtr    window;
  421.     FileRecHndl    frHndl;
  422.     long        attr;
  423.  
  424.     for (window = nil;;) {
  425.  
  426.         if (!window)
  427.             window = FrontWindow();
  428.         else
  429.             window = (WindowPtr)(((WindowPeek)window)->nextWindow);
  430.  
  431.         if (!window) break;        /* All out of windows to get rid of. */
  432.  
  433.         if (!((WindowPeek)window)->visible) continue;
  434.             /* Invisible windows shouldn't be disposed of, since the user may cancel the quit,
  435.             ** and therefore the user will want windows around.  If a "hide on close" window
  436.             ** was closed, it was simply made invisible, so these windows are still actually
  437.             ** intact.  The user will have to show them again, but they still exist. */
  438.  
  439.         if (!IsDAWindow(window)) {
  440.             if (frHndl = (FileRecHndl)GetWRefCon(window)) {
  441.                 attr   = (*frHndl)->fileState.attributes;
  442.                 if (attr & kwIsPalette) continue;
  443.                     /* Closing of all of the windows may be stopped at a
  444.                     ** dirty document, so don't close the palettes. */
  445.             }
  446.         }
  447.  
  448.         if (!DisposeOneWindow(window, kQuit)) return(false);
  449.             /* When DisposeOneWindow returns false, this means that the window
  450.             ** didn't close.  The only cause of this is if the window had a
  451.             ** document that needed saving, and the user cancelled the save.
  452.             ** If the windows succeed in getting closed, then we are
  453.             ** returned true. */
  454.  
  455.         window = nil;
  456.             /* The close of a window may have caused other window to close, so
  457.             ** start looking at windows from the beginning of the list.  This
  458.             ** guarantees that we are always looking at valid window records. */
  459.     }
  460.  
  461.     return(true);
  462. }
  463.  
  464.  
  465.  
  466. /*****************************************************************************/
  467.  
  468.  
  469.  
  470. /* Closes one window.  This window may be an application window, or it may be
  471. ** a system window.  If it is an application window, it may have a document
  472. ** that needs saving. */
  473.  
  474. #pragma segment Window
  475. Boolean    DisposeOneWindow(WindowPtr window, short saveMode)
  476. {
  477.     FileRecHndl    frHndl;
  478.     long        attr;
  479.     OSErr        err;
  480.  
  481.     if (window) {
  482.         if (!IsDAWindow(window)) {
  483.             /* First, if the window is an application window, try saving
  484.             ** the document.  Remember that the user may cancel the save. */
  485.  
  486.             if (frHndl = (FileRecHndl)GetWRefCon(window)) {
  487.  
  488.                 attr = (*frHndl)->fileState.attributes;
  489.                 if (attr & kwHideOnClose) {
  490.                     HideWindow(window);
  491.                     HiliteWindows();
  492.                     WindowGoneFixup(window);
  493.                     return(true);
  494.                 }
  495.  
  496.                 if (!((*frHndl)->fileState.attributes & kwRuntimeOnlyDoc)) {
  497.                     if (IsAppWindow(window)) {
  498.                         err = SaveDocument(frHndl, window, saveMode);
  499.                         if (err) {
  500.                             if (err != userCanceledErr) {
  501.                                 gDialogErr = err;
  502.                                 NewDocumentWindow(nil, 'ERR#', false);
  503.                             }
  504.                             return(false);
  505.                         }        /* Stop closing windows on error or user cancel. */
  506.                     }
  507.                 }
  508.  
  509.                 err = DoFreeWindow(frHndl, window);
  510.                 if (err) return(false);
  511.  
  512.                 DisposeDocument(frHndl);
  513.                     /* If everything is cool, dispose of the document. */
  514.             }
  515.         }
  516.  
  517.         DisposeAnyWindow(window);
  518.         HiliteWindows();
  519.         WindowGoneFixup(window);
  520.             /* Give the application a chance to do any related tasks. */
  521.     }
  522.  
  523.     return(true);
  524. }
  525.  
  526.  
  527.  
  528. /*****************************************************************************/
  529.  
  530.  
  531.  
  532. #pragma segment Window
  533. WindowPtr    SetFilePort(FileRecHndl frHndl)
  534. {
  535.     WindowPtr    oldPort;
  536.  
  537.     GetPort(&oldPort);
  538.     if (frHndl)
  539.         SetPort((*frHndl)->fileState.window);
  540.     return(oldPort);
  541. }
  542.  
  543.  
  544.  
  545. /*****************************************************************************/
  546.  
  547.  
  548.  
  549. #pragma segment Window
  550. void    DoResizeWindow(WindowPtr window, short oldh, short oldv)
  551. {
  552.     FileRecHndl        frHndl;
  553.     WindowPtr        oldPort;
  554.     long            attributes;
  555.     Boolean            growIconSpace;
  556.     Rect            portRct, rct;
  557.     ControlHandle    hScroll, vScroll;
  558.     RgnHandle        updateRgn;
  559.  
  560.     if (!window)                                     return;
  561.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  562.  
  563.     oldPort       = SetFilePort(frHndl);
  564.     attributes    = (*frHndl)->fileState.attributes;
  565.     growIconSpace = (attributes & (kwGrowIcon | (kwHScrollLessGrow - kwHScroll) | (kwVScrollLessGrow - kwVScroll)));
  566.         /* growIconSpace true if window has grow icon or a blank space for one. */
  567.  
  568.     SetOrigin(0, 0);
  569.     portRct = window->portRect;
  570.  
  571.     if (growIconSpace) {
  572.         rct.left = (rct.right  = oldh) - 15;
  573.         rct.top  = (rct.bottom = oldv) - 15;
  574.         EraseRect(&rct);
  575.         InvalRect(&rct);
  576.         rct = portRct;
  577.         rct.left = rct.right  - 15;
  578.         rct.top  = rct.bottom - 15;
  579.         EraseRect(&rct);
  580.     }
  581.  
  582.     SetOrigin(0, -16384);
  583.     if (hScroll = (*frHndl)->fileState.hScroll) {
  584.         HideControl(hScroll);
  585.         rct = (*hScroll)->contrlRect;
  586.         MoveControl(hScroll, rct.left, portRct.bottom - 15 - 16384);
  587.         SizeControl(hScroll, rct.right - rct.left + (portRct.right - portRct.left - oldh), 16);
  588.     }
  589.     if (vScroll = (*frHndl)->fileState.vScroll) {
  590.         HideControl(vScroll);
  591.         rct = (*vScroll)->contrlRect;
  592.         MoveControl(vScroll, portRct.right - 15, rct.top);
  593.         SizeControl(vScroll, 16, rct.bottom - rct.top + (portRct.bottom - portRct.top - oldv));
  594.     }
  595.  
  596.     AdjustScrollBars(window);
  597.  
  598.     if (hScroll)
  599.         ShowControl(hScroll);
  600.     if (vScroll)
  601.         ShowControl(vScroll);
  602.  
  603.     SetOrigin(0, 0);
  604.     if (attributes & kwGrowIcon)
  605.         DoDrawGrowIcon(window, false, false);
  606.  
  607.     BeginContent(window);
  608.     DoResizeContent(window, oldh, oldv);
  609.     updateRgn = NewRgn();
  610.     CopyRgn(((WindowPeek)window)->updateRgn, updateRgn);
  611.     EndContent(window);
  612.     UnionRgn(updateRgn, ((WindowPeek)window)->updateRgn, ((WindowPeek)window)->updateRgn);
  613.     DisposeRgn(updateRgn);
  614.  
  615.     SetPort(oldPort);
  616. }
  617.  
  618.  
  619.  
  620. /*****************************************************************************/
  621.  
  622.  
  623.  
  624. #pragma segment Window
  625. void    DoUpdateSeparate(WindowPtr window, RgnHandle *contRgn, RgnHandle *frameRgn)
  626. {
  627.     RgnHandle    urgn, wrgn;
  628.  
  629.     *contRgn = *frameRgn = nil;
  630.     if (!window) return;
  631.  
  632.     urgn = DoCalcFrameRgn(window);
  633.     wrgn = NewRgn();
  634.  
  635.     DiffRgn(((WindowPeek)window)->updateRgn, urgn, wrgn);
  636.     if (!EmptyRgn(wrgn)) {
  637.         *contRgn = wrgn;
  638.         wrgn = NewRgn();
  639.     }
  640.     SectRgn(((WindowPeek)window)->updateRgn, urgn, wrgn);
  641.  
  642.     if (!EmptyRgn(wrgn))
  643.         *frameRgn = wrgn;
  644.     else
  645.         DisposeRgn(wrgn);
  646.  
  647.     DisposeRgn(urgn);
  648. }
  649.  
  650.  
  651.  
  652. /*****************************************************************************/
  653.  
  654.  
  655.  
  656. #pragma segment Window
  657. void    BeginContent(WindowPtr window)
  658. {
  659.     RgnHandle    updateRgn, frameRgn;
  660.     Point        contOrg;
  661.  
  662.     if (!gBeginUpdateNested++) {
  663.         GetPort(&gOldPort);
  664.         CopyRgn(updateRgn = ((WindowPeek)window)->updateRgn, gKeepUpdateRgn = NewRgn());
  665.         frameRgn = DoCalcFrameRgn(window);
  666.         DiffRgn(((WindowPeek)window)->contRgn, frameRgn, updateRgn);
  667.         DisposeRgn(frameRgn);
  668.         BeginUpdate(window);
  669.     }
  670.     SetPort(window);
  671.     GetContentOrigin(window, &contOrg);
  672.     SetOrigin(contOrg.h, contOrg.v);
  673. }
  674.  
  675.  
  676.  
  677. /*****************************************************************************/
  678.  
  679.  
  680.  
  681. #pragma segment Window
  682. void    EndContent(WindowPtr window)
  683. {
  684.     if (!--gBeginUpdateNested) {
  685.         EndUpdate(window);
  686.         UnionRgn(gKeepUpdateRgn, ((WindowPeek)window)->updateRgn, ((WindowPeek)window)->updateRgn);
  687.         DisposeRgn(gKeepUpdateRgn);
  688.         SetPort(gOldPort);
  689.     }
  690. }
  691.  
  692.  
  693.  
  694. /*****************************************************************************/
  695.  
  696.  
  697.  
  698. #pragma segment Window
  699. void    BeginFrame(WindowPtr window)
  700. {
  701.     RgnHandle    updateRgn, frameRgn, scrollRgn;
  702.  
  703.     if (!gBeginUpdateNested++) {
  704.         GetPort(&gOldPort);
  705.         CopyRgn(updateRgn = ((WindowPeek)window)->updateRgn, gKeepUpdateRgn = NewRgn());
  706.         frameRgn  = DoCalcFrameRgn(window);
  707.         scrollRgn = DoCalcScrollRgn(window);
  708.         DiffRgn(frameRgn, scrollRgn, frameRgn);
  709.         DisposeRgn(scrollRgn);
  710.         SectRgn(((WindowPeek)window)->contRgn, frameRgn, updateRgn);
  711.         DisposeRgn(frameRgn);
  712.         BeginUpdate(window);
  713.     }
  714.     SetPort(window);
  715.     SetOrigin(-16384, 0);
  716. }
  717.  
  718.  
  719.  
  720. /*****************************************************************************/
  721.  
  722.  
  723.  
  724. #pragma segment Window
  725. void    EndFrame(WindowPtr window)
  726. {
  727.     EndContent(window);
  728. }
  729.  
  730.  
  731.  
  732. /*****************************************************************************/
  733.  
  734.  
  735.  
  736. #pragma segment Window
  737. void    AdjustScrollBars(WindowPtr window)
  738. {
  739.     FileRecHndl            frHndl;
  740.     WindowPtr            oldPort;
  741.     ControlHandle        hScroll, vScroll;
  742.     Rect                portRct;
  743.     Point                keepOrg;
  744.     short                h, v, maxVal, val;
  745.     DocScrollBarProc    proc;
  746.  
  747.     if (!window)                                     return;
  748.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  749.  
  750.     oldPort = SetFilePort(frHndl);
  751.     portRct = window->portRect;
  752.  
  753.     keepOrg.h = portRct.left;
  754.     keepOrg.v = portRct.top;
  755.  
  756.     portRct.left += (*frHndl)->fileState.leftSidebar;
  757.     portRct.top  += (*frHndl)->fileState.topSidebar;
  758.  
  759.     hScroll = (*frHndl)->fileState.hScroll;
  760.     vScroll = (*frHndl)->fileState.vScroll;
  761.  
  762.     SetOrigin(0, -16384);
  763.  
  764.     if ((maxVal = (*frHndl)->d.doc.fhInfo.hDocSize) > 0) {
  765.         h = portRct.right - portRct.left;
  766.         if (vScroll)
  767.             h -= 15;
  768.         maxVal -= h;
  769.         if (maxVal < 0)
  770.             maxVal = 0;
  771.         if (hScroll) {
  772.             proc = (DocScrollBarProc)GetCRefCon(hScroll);
  773.             if (proc)
  774.                 (*proc)(frHndl, hScroll, kscrollHAdjust, h);
  775.             else {
  776.                 if (maxVal < (val = GetCtlValue(hScroll)))
  777.                     maxVal = val;
  778.                 if ((*hScroll)->contrlMax != maxVal) {
  779.                     (*hScroll)->contrlMax = maxVal;
  780.                     DoDraw1Control(hScroll, true);
  781.                 }
  782.                 h -= (val = (*frHndl)->fileState.hArrowVal);
  783.                 if (h < val)
  784.                     h = val;
  785.                 (*frHndl)->fileState.hPageVal = h;
  786.             }
  787.         }
  788.     }
  789.  
  790.     if ((maxVal = (*frHndl)->d.doc.fhInfo.vDocSize) > 0) {
  791.         v = portRct.bottom - portRct.top;
  792.         if (hScroll)
  793.             v -= 15;
  794.         maxVal -= v;
  795.         if (maxVal < 0)
  796.             maxVal = 0;
  797.         if (vScroll) {
  798.             proc = (DocScrollBarProc)GetCRefCon(vScroll);
  799.             if (proc)
  800.                 (*proc)(frHndl, vScroll, kscrollVAdjust, v);
  801.             else {
  802.                 if (maxVal < (val = GetCtlValue(vScroll)))
  803.                     maxVal = val;
  804.                 if ((*vScroll)->contrlMax != maxVal) {
  805.                     (*vScroll)->contrlMax = maxVal;
  806.                     DoDraw1Control(vScroll, true);
  807.                 }
  808.                 v -= (val = (*frHndl)->fileState.vArrowVal);
  809.                 if (v < val)
  810.                     v = val;
  811.                 (*frHndl)->fileState.vPageVal = v;
  812.             }
  813.         }
  814.     }
  815.  
  816.     SetOrigin(keepOrg.h, keepOrg.v);
  817.     SetPort(oldPort);
  818. }
  819.  
  820.  
  821.  
  822. /*****************************************************************************/
  823.  
  824.  
  825.  
  826. #pragma segment Window
  827. void    GetContentOrigin(WindowPtr window, Point *contOrg)
  828. {
  829.     FileRecHndl            frHndl;
  830.     ControlHandle        ctl;
  831.     DocScrollBarProc    proc;
  832.  
  833.     contOrg->h = contOrg->v = 0;
  834.  
  835.     if (window) {
  836.         if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  837.         if (ctl = (*frHndl)->fileState.hScroll) {
  838.             contOrg->h = GetCtlValue(ctl);
  839.             if (proc = (DocScrollBarProc)GetCRefCon(ctl))
  840.                 contOrg->h = (*proc)(frHndl, ctl, kscrollGetHOrigin, 0);
  841.         }
  842.         if (ctl = (*frHndl)->fileState.vScroll) {
  843.             contOrg->v = GetCtlValue(ctl);
  844.             if (proc = (DocScrollBarProc)GetCRefCon(ctl))
  845.                 contOrg->v = (*proc)(frHndl, ctl, kscrollGetVOrigin, 0);
  846.         }
  847.         contOrg->h -= (*frHndl)->fileState.leftSidebar;
  848.         contOrg->v -= (*frHndl)->fileState.topSidebar;
  849.     }
  850. }
  851.  
  852.  
  853.  
  854. /*****************************************************************************/
  855.  
  856.  
  857.  
  858. #pragma segment Window
  859. void    SetContentOrigin(WindowPtr window, long newh, long newv)
  860. {
  861.     FileRecHndl        frHndl;
  862.     WindowPtr        oldPort;
  863.     ControlHandle    hScroll, vScroll;
  864.     short            topSide, leftSide, max, dh, dv;
  865.     Point            old, contOrg;
  866.     RgnHandle        updateRgn;
  867.     Rect            contRct;
  868.  
  869.     if (!window)                                     return;
  870.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  871.  
  872.     oldPort = SetFilePort(frHndl);
  873.     hScroll = (*frHndl)->fileState.hScroll;
  874.     vScroll = (*frHndl)->fileState.vScroll;
  875.     GetContentOrigin(window, &old);
  876.     GetContentRect(window, &contRct);
  877.  
  878.     SetOrigin(0, -16384);
  879.     topSide  = (*frHndl)->fileState.topSidebar;
  880.     leftSide = (*frHndl)->fileState.leftSidebar;
  881.  
  882.     if (!hScroll)
  883.         newh = kwNoChange;
  884.     if (newh != kwNoChange) {
  885.         if (newh != kwBotScroll)
  886.             newh += leftSide;
  887.         if (newh < 0)
  888.             newh = 0;
  889.         if (newh > (max = GetCtlMax(hScroll)))
  890.             newh = max;
  891.         if ((*hScroll)->contrlValue != newh) {
  892.             (*hScroll)->contrlValue = newh;
  893.             DoDraw1Control(hScroll, true);
  894.         }
  895.         newh -= leftSide;
  896.     }
  897.  
  898.     if (!vScroll)
  899.         newv = kwNoChange;
  900.     if (newv != kwNoChange) {
  901.         if (newv != kwBotScroll)
  902.             newv += topSide;
  903.         if (newv < 0)
  904.             newv = 0;
  905.         if (newv > (max = GetCtlMax(vScroll)))
  906.             newv = max;
  907.         if ((*vScroll)->contrlValue != newv) {
  908.             (*vScroll)->contrlValue = newv;
  909.             DoDraw1Control(vScroll, true);
  910.         }
  911.         newv -= topSide;
  912.     }
  913.  
  914.     AdjustScrollBars(window);
  915.  
  916.     dh = dv = 0;
  917.     if (newh != kwNoChange)
  918.         dh = old.h - newh;
  919.     if (newv != kwNoChange)
  920.         dv = old.v - newv;
  921.  
  922.     BeginContent(window);
  923.     ScrollRect(&(window->portRect), dh, dv, updateRgn = NewRgn());
  924.     EndContent(window);
  925.  
  926.     OffsetRgn(((WindowPeek)window)->updateRgn, dh, dv);
  927.         /* We want to add the scrolled-in area into the updateRgn.  We
  928.         ** also want to keep the old area.  The old update area is
  929.         ** no longer mapped to the same location, due to the scroll,
  930.         ** so offset it by the amount scrolled.  Once it is offset, we
  931.         ** can add our new update portion to the updateRgn. */
  932.  
  933.     GetContentOrigin(window, &contOrg);
  934.     SetOrigin(contOrg.h, contOrg.v);
  935.     InvalRgn(updateRgn);
  936.     DisposeRgn(updateRgn);
  937.  
  938.     SetOrigin(old.h, old.v);
  939.     SetPort(oldPort);                /* Put things back the way we found them. */
  940.  
  941.     DoScrollFrame(window, dh, dv);    /* There may be changes in the frame due to scrolling. */
  942.  
  943.     DoSetCursor(nil);                /* Cursor region may be invalid due to
  944.                                     ** content being scrolled.  Force it to
  945.                                     ** be recalculated. */
  946. }
  947.  
  948.  
  949.  
  950. /*****************************************************************************/
  951.  
  952.  
  953.  
  954. #pragma segment Window
  955. void    GetContentRect(WindowPtr window, Rect *contRct)
  956. {
  957.     FileRecHndl        frHndl;
  958.     ControlHandle    ctl;
  959.  
  960.     SetRect(contRct, 0, 0, 0, 0);
  961.  
  962.     if (window) {
  963.         if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  964.         *contRct = window->portRect;
  965.         if (ctl = (*frHndl)->fileState.hScroll)
  966.             contRct->bottom -= 15;
  967.         if (ctl = (*frHndl)->fileState.vScroll)
  968.             contRct->right  -= 15;
  969.         contRct->top  += (*frHndl)->fileState.topSidebar;
  970.         contRct->left += (*frHndl)->fileState.leftSidebar;
  971.     }
  972. }
  973.  
  974.  
  975.  
  976. /*****************************************************************************/
  977.  
  978.  
  979.  
  980. #pragma segment Window
  981. void    SetDocSize(FileRecHndl frHndl, long hSize, long vSize)
  982. {
  983.     if (frHndl) {
  984.         if (hSize >= 0)
  985.             (*frHndl)->d.doc.fhInfo.hDocSize = hSize;
  986.         if (vSize >= 0)
  987.             (*frHndl)->d.doc.fhInfo.vDocSize = vSize;
  988.         AdjustScrollBars((*frHndl)->fileState.window);
  989.     }
  990. }
  991.  
  992.  
  993.  
  994. /*****************************************************************************/
  995.  
  996.  
  997.  
  998. #pragma segment Window
  999. void    SetSidebarSize(FileRecHndl frHndl, short newLeft, short newTop)
  1000. {
  1001.     WindowPtr            oldPort, window;
  1002.     Rect                portRct, rct;
  1003.     Point                contOrg;
  1004.     short                oldLeft, oldTop, dh, dv;
  1005.     ControlHandle        ctl;
  1006.     RgnHandle            updateRgn;
  1007.     DrawFrameProcPtr    proc;
  1008.  
  1009.     if (window = (*frHndl)->fileState.window) {
  1010.         oldPort = SetFilePort(frHndl);
  1011.         portRct = window->portRect;
  1012.         SetOrigin(0, -16384);        /* Prepare to modify (redraw) document scrollbars. */
  1013.     }
  1014.  
  1015.     oldLeft = (*frHndl)->fileState.leftSidebar;
  1016.     oldTop  = (*frHndl)->fileState.topSidebar;
  1017.  
  1018.     dh = 0;
  1019.     if (newLeft != kwNoChange) {
  1020.         if (ctl = (*frHndl)->fileState.hScroll) {
  1021.             HideControl(ctl);
  1022.             rct = (*ctl)->contrlRect;
  1023.             rct.left += (newLeft - oldLeft);
  1024.             MoveControl(ctl, rct.left, rct.top);
  1025.             SizeControl(ctl, rct.right - rct.left, 16);
  1026.             ShowControl(ctl);
  1027.         }
  1028.         dh = newLeft - oldLeft;
  1029.     }
  1030.  
  1031.     dv = 0;
  1032.     if (newTop != kwNoChange) {
  1033.         if (ctl = (*frHndl)->fileState.vScroll) {
  1034.             HideControl(ctl);
  1035.             rct = (*ctl)->contrlRect;
  1036.             rct.top += (newTop - oldTop);
  1037.             MoveControl(ctl, rct.left, rct.top);
  1038.             SizeControl(ctl, 16, rct.bottom - rct.top);
  1039.             ShowControl(ctl);
  1040.         }
  1041.         dv = newTop - oldTop;
  1042.     }
  1043.  
  1044.     if (dh < 0)
  1045.         (*frHndl)->fileState.leftSidebar = newLeft;
  1046.     if (dv < 0)
  1047.         (*frHndl)->fileState.topSidebar  = newTop;
  1048.  
  1049.     if (window) {
  1050.         BeginContent(window);
  1051.         ScrollRect(&(window->portRect), dh, dv, updateRgn = NewRgn());
  1052.         EndContent(window);
  1053.     }
  1054.  
  1055.     if (dh)
  1056.         (*frHndl)->fileState.leftSidebar = newLeft;
  1057.     if (dv)
  1058.         (*frHndl)->fileState.topSidebar  = newTop;
  1059.  
  1060.     if (window) {
  1061.         AdjustScrollBars(window);
  1062.  
  1063.         if (proc = (*frHndl)->fileState.drawFrameProc) {
  1064.             SetOrigin(-16384, 0);
  1065.             (*proc)(frHndl, window, false);        /* Draw the application's portion of the frame. */
  1066.         }
  1067.  
  1068.         OffsetRgn(((WindowPeek)window)->updateRgn, dh, dv);
  1069.             /* We want to add the scrolled-in area into the updateRgn.  We
  1070.             ** also want to keep the old area.  The old update area is
  1071.             ** no longer mapped to the same location, due to the scroll,
  1072.             ** so offset it by the amount scrolled.  Once it is offset, we
  1073.             ** can add our new update portion to the updateRgn. */
  1074.         GetContentOrigin(window, &contOrg);
  1075.         SetOrigin(contOrg.h, contOrg.v);
  1076.         InvalRgn(updateRgn);
  1077.         DisposeRgn(updateRgn);
  1078.  
  1079.         SetOrigin(portRct.left, portRct.top);
  1080.         SetPort(oldPort);
  1081.  
  1082.         DoScrollFrame(window, dh, dv);        /* There may be changes in the frame due to scrolling. */
  1083.     }
  1084. }
  1085.  
  1086.  
  1087.  
  1088. /*****************************************************************************/
  1089.  
  1090.  
  1091.  
  1092. #pragma segment Window
  1093. void    SetScrollIndentSize(FileRecHndl frHndl, short newh, short newv)
  1094. {
  1095.     WindowPtr            oldPort, window;
  1096.     Rect                portRct, rct;
  1097.     short                oldh, oldv;
  1098.     ControlHandle        ctl;
  1099.     DrawFrameProcPtr    proc;
  1100.  
  1101.     oldPort = SetFilePort(frHndl);
  1102.     GetPort(&window);
  1103.     portRct = window->portRect;
  1104.     SetOrigin(0, -16384);
  1105.  
  1106.     oldh = (*frHndl)->fileState.hScrollIndent;
  1107.     oldv = (*frHndl)->fileState.vScrollIndent;
  1108.  
  1109.     if (newh != kwNoChange) {
  1110.         if (ctl = (*frHndl)->fileState.hScroll) {
  1111.             HideControl(ctl);
  1112.             rct = (*ctl)->contrlRect;
  1113.             rct.left += (newh - oldh);
  1114.             MoveControl(ctl, rct.left, rct.top);
  1115.             SizeControl(ctl, rct.right - rct.left, 16);
  1116.             ShowControl(ctl);
  1117.         }
  1118.         (*frHndl)->fileState.hScrollIndent = newh;
  1119.     }
  1120.  
  1121.     if (newv != kwNoChange) {
  1122.         if (ctl = (*frHndl)->fileState.vScroll) {
  1123.             HideControl(ctl);
  1124.             rct = (*ctl)->contrlRect;
  1125.             rct.top += (newv - oldv);
  1126.             MoveControl(ctl, rct.left, rct.top);
  1127.             SizeControl(ctl, 16, rct.bottom - rct.top);
  1128.             ShowControl(ctl);
  1129.         }
  1130.         (*frHndl)->fileState.vScrollIndent = newv;
  1131.     }
  1132.  
  1133.     if (proc = (*frHndl)->fileState.drawFrameProc) {
  1134.         SetOrigin(-16384, 0);
  1135.         (*proc)(frHndl, window, false);        /* Draw the application's portion of the frame. */
  1136.     }
  1137.  
  1138.     SetOrigin(portRct.left, portRct.top);
  1139.     SetPort(oldPort);
  1140. }
  1141.  
  1142.  
  1143.  
  1144. /*****************************************************************************/
  1145.  
  1146.  
  1147.  
  1148. #pragma segment Window
  1149. FileRecHndl    GetNextDocument(WindowPtr window, OSType sftype)
  1150. {
  1151.     if (!(window = GetNextWindow(window, sftype))) return(nil);
  1152.     return((FileRecHndl)GetWRefCon(window));
  1153. }
  1154.  
  1155.  
  1156.  
  1157. /*****************************************************************************/
  1158.  
  1159.  
  1160.  
  1161. #pragma segment Window
  1162. WindowPtr    GetNextWindow(WindowPtr window, OSType sftype)
  1163. {
  1164.     WindowPeek    wpeek;
  1165.     FileRecHndl    frHndl;
  1166.  
  1167.     if (window == (WindowPtr)-1)
  1168.         window = nil;
  1169.  
  1170.     if (!window)
  1171. #ifdef __SYSEQU__
  1172.         wpeek = *(WindowPeek *)WindowList;
  1173. #else
  1174.         wpeek = WindowList;
  1175. #endif
  1176.     else wpeek = ((WindowPeek)window)->nextWindow;
  1177.  
  1178.     for (; wpeek; wpeek = wpeek->nextWindow) {
  1179.  
  1180.         if ((wpeek->windowKind < userKind) && (wpeek->windowKind != dialogKind)) continue;
  1181.             /* Not a dialog or user window, so skip it. */
  1182.  
  1183.         if (!sftype) break;
  1184.             /* Request is for any window.  We have a window, so break. */
  1185.  
  1186.         if (!(frHndl = (FileRecHndl)GetWRefCon((WindowPtr)wpeek))) {
  1187.  
  1188.             /* Window doesn't have an frHndl in the refcon, so there is only so much that
  1189.             ** we can check.  See if the request is specific to dialogs or regular windows.
  1190.             ** If so, then return the window. */
  1191.  
  1192.             if (sftype == 'DLOG')
  1193.                 if (wpeek->windowKind == dialogKind) break;
  1194.  
  1195.             if (sftype == 'WIND')
  1196.                 if (wpeek->windowKind >= userKind) break;
  1197.  
  1198.             continue;        /* Doesn't match request, so try next window. */
  1199.         }
  1200.         if ((*frHndl)->fileState.sfType == sftype) break;        /* Bingo. */
  1201.             /* The sfType field is the first 4 bytes in the refcon handle.  If you don't
  1202.             ** want to use the application framework completely, but you still want this
  1203.             ** function, then all you have to do is place an identifier in the first 4
  1204.             ** bytes of the refcon handle. */
  1205.     }
  1206.  
  1207.     return((WindowPtr)wpeek);
  1208. }
  1209.  
  1210.  
  1211.  
  1212. /*****************************************************************************/
  1213.  
  1214.  
  1215.  
  1216. #pragma segment Window
  1217. WindowPtr    GetPreviousWindow(WindowPtr window)
  1218. {
  1219.     WindowPeek    wpeek;
  1220.     WindowPtr    lastWindow;
  1221.  
  1222.     if (window == (WindowPtr)-1) return((WindowPtr)-1);
  1223.  
  1224. #ifdef __SYSEQU__
  1225.     wpeek = *(WindowPeek *)WindowList;
  1226. #else
  1227.     wpeek = WindowList;
  1228. #endif
  1229.  
  1230.     for (lastWindow = (WindowPtr)-1; wpeek; wpeek = wpeek->nextWindow) {
  1231.         if (window == (WindowPtr)wpeek) break;
  1232.         lastWindow = (WindowPtr)wpeek;
  1233.     }
  1234.  
  1235.     return(lastWindow);
  1236. }
  1237.  
  1238.  
  1239.  
  1240. /*****************************************************************************/
  1241.  
  1242.  
  1243.  
  1244. #pragma segment Window
  1245. void    DoZoomWindow(WindowPtr window, EventRecord *event, short zoomDir)
  1246. {
  1247.     Boolean        doit;
  1248.     Rect        old;
  1249.     FileRecHndl    frHndl;
  1250.     short        hDocSize, vDocSize;
  1251.  
  1252.     if (!window)                                     return;
  1253.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  1254.  
  1255.     doit = true;
  1256.     if (event)
  1257.         doit = TrackBox(window, event->where, zoomDir);
  1258.  
  1259.     if (doit) {
  1260.         old       = GetWindowContentRect(window);
  1261.         hDocSize  = (*frHndl)->d.doc.fhInfo.hDocSize;
  1262.         hDocSize += (*frHndl)->fileState.leftSidebar;
  1263.         if ((*frHndl)->fileState.vScroll)
  1264.             hDocSize += 15;
  1265.         vDocSize  = (*frHndl)->d.doc.fhInfo.vDocSize;
  1266.         vDocSize += (*frHndl)->fileState.topSidebar;
  1267.         if ((*frHndl)->fileState.hScroll)
  1268.             vDocSize += 15;
  1269.  
  1270.         if (hDocSize < (*frHndl)->fileState.windowSizeBounds.left)
  1271.             hDocSize = (*frHndl)->fileState.windowSizeBounds.left;
  1272.         if (vDocSize < (*frHndl)->fileState.windowSizeBounds.top)
  1273.             vDocSize = (*frHndl)->fileState.windowSizeBounds.top;
  1274.  
  1275.         ZoomToWindowDevice(window, hDocSize, vDocSize, zoomDir, false);
  1276.         DoResizeWindow(window, old.right - old.left, old.bottom - old.top);
  1277.     }
  1278. }
  1279.  
  1280.  
  1281.  
  1282. /*****************************************************************************/
  1283. /*****************************************************************************/
  1284.  
  1285.  
  1286.  
  1287. #pragma segment Window
  1288. RgnHandle    DoCalcFrameRgn(WindowPtr window)
  1289. {
  1290.     FileRecHndl            frHndl;
  1291.     WindowPtr            oldPort;
  1292.     RgnHandle            urgn, wrgn;
  1293.     short                i;
  1294.     Rect                rct;
  1295.     Point                l2g;
  1296.     CalcFrameRgnProcPtr    proc;
  1297.  
  1298.     urgn = NewRgn();
  1299.     if (!window)                                     return(urgn);
  1300.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return(urgn);
  1301.  
  1302.     oldPort = SetFilePort(frHndl);
  1303.     SetOrigin(0, 0);
  1304.  
  1305.     if (proc = (*frHndl)->fileState.calcFrameRgnProc)
  1306.         (*proc)(frHndl, window, urgn);
  1307.  
  1308.     wrgn = NewRgn();
  1309.     for (i = 0; i < 2; ++i) {
  1310.         rct = window->portRect;
  1311.         if (i)
  1312.             rct.bottom = (*frHndl)->fileState.topSidebar;
  1313.         else
  1314.             rct.right  = (*frHndl)->fileState.leftSidebar;
  1315.         RectRgn(wrgn, &rct);
  1316.         UnionRgn(urgn, wrgn, urgn);
  1317.     }
  1318.     DisposeRgn(wrgn);
  1319.  
  1320.     l2g.h = l2g.v = 0;
  1321.     LocalToGlobal(&l2g);
  1322.     OffsetRgn(urgn, l2g.h, l2g.v);
  1323.  
  1324.     wrgn = DoCalcScrollRgn(window);
  1325.     UnionRgn(urgn, wrgn, urgn);
  1326.     DisposeRgn(wrgn);
  1327.  
  1328.     SetPort(oldPort);
  1329.     return(urgn);
  1330. }
  1331.  
  1332.  
  1333.  
  1334. /*****************************************************************************/
  1335.  
  1336.  
  1337.  
  1338. #pragma segment Window
  1339. RgnHandle    DoCalcScrollRgn(WindowPtr window)
  1340. {
  1341.     FileRecHndl            frHndl;
  1342.     WindowPtr            oldPort;
  1343.     RgnHandle            urgn, wrgn;
  1344.     short                i;
  1345.     long                attributes;
  1346.     Boolean                growIconSpace;
  1347.     Rect                rct;
  1348.     Point                l2g;
  1349.     ControlHandle        ctl;
  1350.  
  1351.     urgn = NewRgn();
  1352.     if (!window) return(urgn);
  1353.     if (!window)                                     return(urgn);
  1354.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return(urgn);
  1355.  
  1356.     oldPort = SetFilePort(frHndl);
  1357.     SetOrigin(0, 0);
  1358.  
  1359.     attributes    = (*frHndl)->fileState.attributes;
  1360.     growIconSpace = (attributes & (kwGrowIcon | (kwHScrollLessGrow - kwHScroll) | (kwVScrollLessGrow - kwVScroll)));
  1361.         /* growIconSpace true if window has grow icon or a blank space for one. */
  1362.  
  1363.     wrgn = NewRgn();
  1364.     if (growIconSpace) {
  1365.         rct = window->portRect;
  1366.         rct.left = rct.right  - 15;
  1367.         rct.top  = rct.bottom - 15;
  1368.         RectRgn(wrgn, &rct);
  1369.         UnionRgn(urgn, wrgn, urgn);
  1370.     }
  1371.     for (i = 0; i < 2; ++i) {
  1372.         ctl = (i) ? (*frHndl)->fileState.vScroll : (*frHndl)->fileState.hScroll;
  1373.         if (ctl) {
  1374.             rct = (*ctl)->contrlRect;
  1375.             if (i)
  1376.                 rct.top  -= (*frHndl)->fileState.vScrollIndent;
  1377.             else
  1378.                 rct.left -= (*frHndl)->fileState.hScrollIndent;
  1379.             OffsetRect(&rct, 0, 16384);
  1380.             RectRgn(wrgn, &rct);
  1381.             UnionRgn(urgn, wrgn, urgn);
  1382.         }
  1383.     }
  1384.     DisposeRgn(wrgn);
  1385.  
  1386.     l2g.h = l2g.v = 0;
  1387.     LocalToGlobal(&l2g);
  1388.     OffsetRgn(urgn, l2g.h, l2g.v);
  1389.  
  1390.     SetPort(oldPort);
  1391.     return(urgn);
  1392. }
  1393.  
  1394.  
  1395.  
  1396. /*****************************************************************************/
  1397.  
  1398.  
  1399.  
  1400. #pragma segment Window
  1401. void    DoContentClick(WindowPtr window, EventRecord *event, Boolean firstClick)
  1402. {
  1403.     FileRecHndl            frHndl;
  1404.     ContentClickProcPtr    proc;
  1405.  
  1406.     if (!IsDAWindow(window))
  1407.         if (frHndl = (FileRecHndl)GetWRefCon(window))
  1408.             if (proc = (*frHndl)->fileState.contentClickProc)
  1409.                 (*proc)(window, event, firstClick);
  1410. }
  1411.  
  1412.  
  1413.  
  1414. /*****************************************************************************/
  1415.  
  1416.  
  1417.  
  1418. #pragma segment Window
  1419. void    DoDragWindow(WindowPtr window, EventRecord *event, Rect bounds)
  1420. {
  1421.     WindowPtr    oldPort, fwindow;
  1422.     GrafPort    bigPort;
  1423.     WindowPeek    wpeek;
  1424.     FileRecHndl    frHndl;
  1425.     RgnHandle    dragRgn;
  1426.     Point        offset;
  1427.     Rect        contRct;
  1428.     long        wkind;
  1429.  
  1430.     GetPort(&oldPort);
  1431.  
  1432.     OpenPort(&bigPort);
  1433.     CopyRgn(GetGrayRgn(), bigPort.visRgn);
  1434.     bigPort.portRect = (*bigPort.visRgn)->rgnBBox;
  1435.  
  1436.     if (gSystemVersion >= 0x0700) {
  1437.         HMGetBalloonWindow(&fwindow);
  1438.         if (fwindow)
  1439.             DiffRgn(bigPort.visRgn, ((WindowPeek)fwindow)->strucRgn, bigPort.visRgn);
  1440.     }
  1441.  
  1442.     fwindow = (WindowPtr)-1;
  1443.     if (!IsDAWindow(window)) {
  1444.         if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  1445.         wkind   = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  1446.         fwindow = FrontWindowOfType(wkind, true);
  1447.         for (wpeek = (WindowPeek)FrontWindow(); wpeek; wpeek = wpeek->nextWindow) {
  1448.             if (fwindow == (WindowPtr)wpeek) break;
  1449.             DiffRgn(bigPort.visRgn, wpeek->strucRgn, bigPort.visRgn);
  1450.         }
  1451.     }
  1452.  
  1453.     CopyRgn(((WindowPeek)window)->strucRgn, dragRgn = NewRgn());
  1454.     *(long *)&offset = DragGrayRgn(dragRgn, event->where, &bounds, &bounds, noConstraint, nil);
  1455.  
  1456.     DisposeRgn(dragRgn);
  1457.     ClosePort(&bigPort);
  1458.     SetPort(oldPort);
  1459.  
  1460.     if ((offset.h != 0x8000) || (offset.v != 0x8000)) {
  1461.         contRct = (*((WindowPeek)window)->contRgn)->rgnBBox;
  1462.         OffsetRect(&contRct, offset.h, offset.v);
  1463.         MoveWindow(window, contRct.left, contRct.top, false);
  1464.     }
  1465.  
  1466.     if (!(event->modifiers & cmdKey))
  1467.         CleanSendInFront(window, fwindow);
  1468. }
  1469.  
  1470.  
  1471.  
  1472. /*****************************************************************************/
  1473.  
  1474.  
  1475.  
  1476. #pragma segment Window
  1477. void    DoDrawFrame(WindowPtr window, Boolean activate)
  1478. {
  1479.     FileRecHndl            frHndl;
  1480.     WindowPtr            oldPort;
  1481.     Rect                worg;
  1482.     long                attributes;
  1483.     DrawFrameProcPtr    proc;
  1484.  
  1485.     if (window) {
  1486.         if (frHndl = (FileRecHndl)GetWRefCon(window)) {
  1487.             oldPort = SetFilePort(frHndl);
  1488.             worg    = window->portRect;
  1489.             SetOrigin(0, 0);
  1490.     
  1491.             attributes = (*frHndl)->fileState.attributes;
  1492.             if (attributes & kwGrowIcon)
  1493.                 DoDrawGrowIcon(window, false, false);
  1494.     
  1495.             SetOrigin(0, -16384);
  1496.             DoDrawControls(window, true);
  1497.             SetOrigin(-16384, 0);
  1498.             if (proc = (*frHndl)->fileState.drawFrameProc)
  1499.                 (*proc)(frHndl, window, activate);
  1500.     
  1501.             SetOrigin(worg.left, worg.top);
  1502.             SetPort(oldPort);
  1503.         }
  1504.     }
  1505. }
  1506.  
  1507.  
  1508.  
  1509. /*****************************************************************************/
  1510.  
  1511.  
  1512.  
  1513. #pragma segment Window
  1514. OSErr    DoFreeDocument(FileRecHndl frHndl)
  1515. {
  1516.     FreeDocumentProcPtr    proc;
  1517.     OSErr                err;
  1518.  
  1519.     err = noErr;
  1520.     if (proc = (*frHndl)->fileState.freeDocumentProc)
  1521.         err = (*proc)(frHndl);
  1522.     return(err);
  1523. }
  1524.  
  1525.  
  1526.  
  1527. /*****************************************************************************/
  1528.  
  1529.  
  1530.  
  1531. #pragma segment Window
  1532. OSErr    DoFreeWindow(FileRecHndl frHndl, WindowPtr window)
  1533. {
  1534.     FreeWindowProcPtr    proc;
  1535.     OSErr                err;
  1536.  
  1537.     err = noErr;
  1538.     if (proc = (*frHndl)->fileState.freeWindowProc)
  1539.         err = (*proc)(frHndl, window);
  1540.     return(err);
  1541. }
  1542.  
  1543.  
  1544.  
  1545. /*****************************************************************************/
  1546.  
  1547.  
  1548.  
  1549. #pragma segment Window
  1550. OSErr    DoImageDocument(FileRecHndl frHndl)
  1551. {
  1552.     ImageProcPtr    proc;
  1553.     OSErr            err;
  1554.  
  1555.     err = noErr;
  1556.     if (proc = (*frHndl)->fileState.imageProc)
  1557.         err = (*proc)(frHndl);
  1558.     return(err);
  1559. }
  1560.  
  1561.  
  1562.  
  1563. /*****************************************************************************/
  1564.  
  1565.  
  1566.  
  1567. #pragma segment Window
  1568. OSErr    DoInitContent(FileRecHndl frHndl, WindowPtr window)
  1569. {
  1570.     InitContentProcPtr    proc;
  1571.     OSErr                err;
  1572.  
  1573.     err = noErr;
  1574.     if (proc = (*frHndl)->fileState.initContentProc)
  1575.         err = (*proc)(frHndl, window);
  1576.     return(err);
  1577. }
  1578.  
  1579.  
  1580.  
  1581. /*****************************************************************************/
  1582.  
  1583.  
  1584.  
  1585. #pragma segment Window
  1586. Boolean    DoKeyDown(EventRecord *event)
  1587. {
  1588.     char                key;
  1589.     WindowPtr            window, fwindow;
  1590.     FileRecHndl            frHndl;
  1591.     ContentKeyProcPtr    proc;
  1592.     Boolean                passThrough;
  1593.     short                menuID, menuItem, menuItem2, charsUsed;
  1594.     long                menuVal, attr, wkind;
  1595.     Str32                str;
  1596.     OSType                sftype;
  1597.     OSErr                err;
  1598.     DoMenuItemProcPtr    mproc, mp;
  1599.  
  1600.     key = event->message & charCodeMask;
  1601.     if (event->modifiers & cmdKey) {        /* If command key down... */
  1602.         if (event->what == keyDown) {
  1603.             DoAdjustMenus();                /* Prepare menus properly. */
  1604.             menuVal   = MenuKey(key);
  1605.             menuID    = HiWord(menuVal);
  1606.             menuItem  = LoWord(menuVal);
  1607.             menuItem2 = MapMItem(menuID, menuItem);
  1608.             if (menuID) {
  1609.                 mproc = DoMenuItem;
  1610.                 if (IsAppWindow(window = FrontWindow()))
  1611.                     if (mp = (*(FileRecHndl)GetWRefCon(window))->fileState.doMenuItemProc)
  1612.                         mproc = mp;
  1613.                 if (!(*mproc)(window, menuID, menuItem2)) {
  1614.                     GetIndString(str, menuID, menuItem);
  1615.                     if (str[0]) {
  1616.                         p2dec(str, &charsUsed);
  1617.                         if (str[0] > charsUsed + 2) {
  1618.                             if (str[charsUsed + 2] == '\'') {
  1619.                                 BlockMove(str + charsUsed + 3, (Ptr)&sftype, sizeof(OSType));
  1620.                                 if (window = GetNextWindow(nil, sftype)) {
  1621.                                     frHndl = (FileRecHndl)GetWRefCon(window);
  1622.                                     attr   = (*frHndl)->fileState.attributes;
  1623.                                     if (attr & kwHideOnClose) {
  1624.                                         if (!((WindowPeek)window)->visible)
  1625.                                             ShowHide(window, true);
  1626.                                         wkind = (attr & (kwIsPalette | kwIsModalDialog));
  1627.                                         if (!(fwindow = FrontWindowOfType(wkind, false)))
  1628.                                             fwindow = (WindowPtr)-1;
  1629.                                         CleanSendInFront(window, fwindow);
  1630.                                     }
  1631.                                     else window = nil;
  1632.                                 }
  1633.                                 if (!window) {
  1634.                                     err = NewDocumentWindow(&frHndl, sftype, true);
  1635.                                     if (!err) {
  1636.                                         window = (*frHndl)->fileState.window;
  1637.                                         if (!((WindowPeek)window)->visible)
  1638.                                             ShowHide(window, true);
  1639.                                         wkind = (attr & (kwIsPalette | kwIsModalDialog));
  1640.                                         if (!(fwindow = FrontWindowOfType(wkind, false)))
  1641.                                             fwindow = (WindowPtr)-1;
  1642.                                         CleanSendInFront(window, fwindow);
  1643.                                     }
  1644.                                     else {
  1645.                                         gDialogErr = err;
  1646.                                         NewDocumentWindow(nil, 'ERR#', false);
  1647.                                     }
  1648.                                 }
  1649.                             }
  1650.                         }
  1651.                     }
  1652.                 }
  1653.                 HiliteMenu(0);        /* Unhighlight what MenuKey hilited. */
  1654.                 DoSetCursor(nil);
  1655.                 return(false);
  1656.             }
  1657.         }
  1658.         else return(false);
  1659.     }
  1660.  
  1661.     for (window = nil; window = GetNextWindow(window, 0);) {
  1662.         if (!((WindowPeek)window)->visible) continue;
  1663.         if (frHndl = (FileRecHndl)GetWRefCon(window)) {
  1664.             if (proc = (*frHndl)->fileState.contentKeyProc) {
  1665.                 passThrough = false;
  1666.                 if ((*proc)(window, event, &passThrough)) return(true);
  1667.                 if (!passThrough) break;
  1668.             }
  1669.         }
  1670.     }
  1671.  
  1672.     return(false);
  1673. }
  1674.  
  1675.  
  1676.  
  1677. /*****************************************************************************/
  1678.  
  1679.  
  1680.  
  1681. #pragma segment Window
  1682. void    DoMouseDown(EventRecord *event)
  1683. {
  1684.     WindowPtr            window, fwindow, dlog;
  1685.     FileRecHndl            frHndl;
  1686.     Rect                contentRct, old, growLimits, tearRect;
  1687.     Point                pt;
  1688.     short                part, menuID, menuItem, menuItem2, charsUsed;
  1689.     long                menuVal, size, wkind, attr;
  1690.     Str63                str;
  1691.     OSType                sftype;
  1692.     OSErr                err;
  1693.     DoMenuItemProcPtr    mproc, mp;
  1694.  
  1695.     gCursorPtr = nil;
  1696.         /* No shortcuts when we recalculate the cursor region. */
  1697.  
  1698.     part = FindWindow(event->where, &window);
  1699.  
  1700.     frHndl = nil;
  1701.     if (window)
  1702.         frHndl = (FileRecHndl)GetWRefCon(window);
  1703.  
  1704.     if (part != inContent)
  1705.         DoSetCursor(&qd.arrow);
  1706.  
  1707.     dlog = FrontWindowOfType(kwIsModalDialog, true);
  1708.     if ((dlog) && (window != dlog)) {
  1709.         if (part != inMenuBar) {
  1710.             SysBeep(1);
  1711.             return;
  1712.         }
  1713.     }
  1714.  
  1715.     switch(part) {
  1716.  
  1717.         case inContent:
  1718.  
  1719.             if (!IsAppWindow(window)) {
  1720.                 if (window != FrontWindow()) {
  1721.                     SelectWindow(window);
  1722.                     HiliteWindows();
  1723.                 }
  1724.                 break;
  1725.             }
  1726.  
  1727.             wkind   = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  1728.             fwindow = FrontWindowOfType(wkind, true);
  1729.                 /* fwindow guaranteed, since worst case we find ourself. */
  1730.  
  1731.             if (window == fwindow) {
  1732.                 DoContentClick(window, event, false);
  1733.                 break;
  1734.             }        /* The window is the frontmost of this type, so handle the click. */
  1735.  
  1736.             CleanSendInFront(window, fwindow);
  1737.  
  1738.             if ((*frHndl)->fileState.attributes & kwDoFirstClick) {
  1739.                 DoUpdate(window);
  1740.                 contentRct = GetWindowContentRect(window);
  1741.                 if (PtInRect(event->where, &contentRct))
  1742.                     DoContentClick(window, event, true);
  1743.             }
  1744.             break;
  1745.  
  1746.         case inDrag:
  1747.             DoDragWindow(window, event, qd.screenBits.bounds);
  1748.             break;        /* Pass screenBits.bounds to get all gDevices. */
  1749.  
  1750.         case inGoAway:
  1751.             if (TrackGoAway(window, event->where))
  1752.                 DisposeOneWindow(window, kClose);
  1753.             break;
  1754.  
  1755.         case inGrow:
  1756.             old = GetWindowContentRect(window);
  1757.             growLimits = (*frHndl)->fileState.windowSizeBounds;
  1758.             ++growLimits.right;
  1759.             ++growLimits.bottom;
  1760.             if (size = GrowWindow(window, event->where, &growLimits)) {
  1761.                 pt = *(Point *)&size;
  1762.                 SizeWindow(window, pt.h, pt.v, true);
  1763.                 DoResizeWindow(window, old.right - old.left, old.bottom - old.top);
  1764.             }
  1765.             break;
  1766.  
  1767.         case inMenuBar:        /* Process mouse menu command (if any). */
  1768.             DoAdjustMenus();
  1769.             DoSetCursor(&qd.arrow);
  1770.             menuVal  = MenuSelect(event->where);
  1771.             menuID   = HiWord(menuVal);
  1772.             menuItem = LoWord(menuVal);
  1773.             if (menuItem == -1)
  1774.                 menuItem = CountMItems(GetMHandle(menuID));
  1775.             menuItem2 = MapMItem(menuID, menuItem);
  1776.             mproc = DoMenuItem;
  1777.             if (IsAppWindow(window = FrontWindow()))
  1778.                 if (mp = (*(FileRecHndl)GetWRefCon(window))->fileState.doMenuItemProc)
  1779.                     mproc = mp;
  1780.             if (!(*mproc)(window, menuID, menuItem2)) {
  1781.                 GetIndString(str, menuID, menuItem);
  1782.                 if (str[0]) {
  1783.                     p2dec(str, &charsUsed);
  1784.                     if (str[0] > charsUsed + 2) {
  1785.                         if (str[charsUsed + 2] == '\'') {
  1786.                             BlockMove(str + charsUsed + 3, (Ptr)&sftype, sizeof(OSType));
  1787.                             if (window = GetNextWindow(nil, sftype)) {
  1788.                                 frHndl = (FileRecHndl)GetWRefCon(window);
  1789.                                 attr   = (*frHndl)->fileState.attributes;
  1790.                                 if (attr & kwHideOnClose) {
  1791.                                     if (menuItem2 == -1) {
  1792.                                         GetItem(GetMHandle(menuID), menuItem, str);
  1793.                                         BlockMove(str + 1, &tearRect, sizeof(Rect));
  1794.                                         MoveWindow(window, tearRect.left, tearRect.top, false);
  1795.                                     }
  1796.                                     if (!((WindowPeek)window)->visible)
  1797.                                         ShowHide(window, true);
  1798.                                     wkind = (attr & (kwIsPalette | kwIsModalDialog));
  1799.                                     if (!(fwindow = FrontWindowOfType(wkind, false)))
  1800.                                         fwindow = (WindowPtr)-1;
  1801.                                     CleanSendInFront(window, fwindow);
  1802.                                 }
  1803.                                 else window = nil;
  1804.                             }
  1805.                             if (!window) {
  1806.                                 err = NewDocumentWindow(&frHndl, sftype, true);
  1807.                                 if (!err) {
  1808.                                     window = (*frHndl)->fileState.window;
  1809.                                     attr   = (*frHndl)->fileState.attributes;
  1810.                                     if (!((WindowPeek)window)->visible)
  1811.                                         ShowHide(window, true);
  1812.                                     wkind = (attr & (kwIsPalette | kwIsModalDialog));
  1813.                                     if (!(fwindow = FrontWindowOfType(wkind, false)))
  1814.                                         fwindow = (WindowPtr)-1;
  1815.                                     CleanSendInFront(window, fwindow);
  1816.                                 }
  1817.                                 else {
  1818.                                     gDialogErr = err;
  1819.                                     NewDocumentWindow(nil, 'ERR#', false);
  1820.                                 }
  1821.                             }
  1822.                         }
  1823.                     }
  1824.                 }
  1825.             }
  1826.             HiliteMenu(0);        /* Unhighlight what MenuSelect hilited. */
  1827.             break;
  1828.  
  1829.         case inSysWindow:    /* Let the system handle the mouseDown. */
  1830.             SystemClick(event, window);
  1831.             break;
  1832.  
  1833.         case inZoomIn:
  1834.         case inZoomOut:
  1835.             DoZoomWindow(window, event, part);
  1836.             break;
  1837.  
  1838.     }
  1839. }
  1840.  
  1841.  
  1842.  
  1843. /*****************************************************************************/
  1844.  
  1845.  
  1846.  
  1847. #pragma segment Window
  1848. short    MapMItem(short menuID, short menuItem)
  1849. {
  1850.     Str32    str;
  1851.  
  1852.     if (menuID == 128)
  1853.         return(menuItem);
  1854.  
  1855.     GetIndString(str, menuID, menuItem);
  1856.     if (str[0])
  1857.         menuItem = p2dec(str, nil);
  1858.  
  1859.     return(menuItem);
  1860. }
  1861.  
  1862.  
  1863.  
  1864. /*****************************************************************************/
  1865.  
  1866.  
  1867.  
  1868. #pragma segment Window
  1869. short    UnmapMItem(short menuID, short menuItem)
  1870. {
  1871.     Str32    str;
  1872.     short    i, j;
  1873.  
  1874.     if (menuID == 128) return(menuItem);
  1875.     if (menuItem) {
  1876.         for (i = 1;; ++i) {
  1877.             GetIndString(str, menuID, i);
  1878.             if (!str[0]) return(menuItem);
  1879.             j = p2dec(str, nil);
  1880.             if (menuItem == j) return(i);
  1881.         }
  1882.     }
  1883. }
  1884.  
  1885.  
  1886.  
  1887. /*****************************************************************************/
  1888.  
  1889.  
  1890.  
  1891. #pragma segment Window
  1892. OSErr    DoReadDocument(FileRecHndl frHndl)
  1893. {
  1894.     ReadDocumentProcPtr    proc;
  1895.     OSErr                err;
  1896.  
  1897.     err = noErr;
  1898.     if (proc = (*frHndl)->fileState.readDocumentProc)
  1899.         err = (*proc)(frHndl);
  1900.     return(err);
  1901. }
  1902.  
  1903.  
  1904.  
  1905. /*****************************************************************************/
  1906.  
  1907.  
  1908.  
  1909. #pragma segment Window
  1910. OSErr    DoReadDocumentHeader(FileRecHndl frHndl)
  1911. {
  1912.     ReadDocumentHeaderProcPtr    proc;
  1913.     OSErr                        err;
  1914.  
  1915.     err = noErr;
  1916.     if ((*frHndl)->fileState.refNum)
  1917.         if (proc = (*frHndl)->fileState.readDocumentHeaderProc)
  1918.             err = (*proc)(frHndl);
  1919.     return(err);
  1920. }
  1921.  
  1922.  
  1923.  
  1924. /*****************************************************************************/
  1925.  
  1926.  
  1927.  
  1928. #pragma segment Window
  1929. OSErr    DefaultReadDocumentHeader(FileRecHndl frHndl)
  1930. {
  1931.     short    refNum, vers, resAlreadyOpen, oldRes;
  1932.     OSErr    err;
  1933.     char    hstate;
  1934.     Ptr        ptr1, ptr2;
  1935.     long    count, attr;
  1936.     OSType    sftype;
  1937.     Handle    hndl;
  1938.  
  1939.     if (err = SetFPos(refNum = (*frHndl)->fileState.refNum, fsFromStart, 0)) return(err);
  1940.  
  1941.     attr   = (*frHndl)->fileState.attributes;
  1942.     sftype = (*frHndl)->fileState.sfType;
  1943.  
  1944.     if (attr & kwDefaultDocHeader) {
  1945.         if (sftype != MovieFileType) {
  1946.             if (attr & kwHeaderIsResource) {
  1947.                 resAlreadyOpen = (*frHndl)->fileState.resRefNum;
  1948.                 UseDocResFile(frHndl, &oldRes, fsRdWrPerm);
  1949.                 hndl = Get1Resource('DFDH', 128);
  1950.                 err  = ResError();
  1951.                 if (!hndl) err = memFullErr;
  1952.                 if (!err) {
  1953.                     ptr1   = (Ptr)&((*frHndl)->d.doc);
  1954.                     ptr2   = (Ptr)&((*frHndl)->d.doc.fhInfo.endDocHeaderInfo);
  1955.                     count  = (long)ptr2 - (long)ptr1;
  1956.                     BlockMove(*hndl, ptr1, count);
  1957.                 }
  1958.                 if (hndl)
  1959.                     ReleaseResource(hndl);
  1960.                 if (!resAlreadyOpen)
  1961.                     CloseDocResFile(frHndl);
  1962.                 UseResFile(oldRes);
  1963.             }
  1964.             else {
  1965.                 if (!err) {        /* Read header info from file. */
  1966.                     hstate = HGetState((Handle)frHndl);
  1967.                     HLock((Handle)frHndl);
  1968.                     ptr1   = (Ptr)&((*frHndl)->d.doc);
  1969.                     ptr2   = (Ptr)&((*frHndl)->d.doc.fhInfo.endDocHeaderInfo);
  1970.                     count  = (long)ptr2 - (long)ptr1;
  1971.                     err    = FSRead(refNum, &count, ptr1);
  1972.                     HSetState((Handle)frHndl, hstate);
  1973.                 }
  1974.             }
  1975.             if (!err) {
  1976.                 vers = (*frHndl)->d.doc.fhInfo.version;
  1977.                 if ((vers < gMinVersion) || (vers > gMaxVersion))
  1978.                     err = kWrongVersion;
  1979.             }
  1980.         }
  1981.     }
  1982.  
  1983.     return(err);
  1984. }
  1985.  
  1986.  
  1987.  
  1988. /*****************************************************************************/
  1989.  
  1990.  
  1991.  
  1992. #pragma segment Window
  1993. OSErr    DoWriteDocument(FileRecHndl frHndl)
  1994. {
  1995.     WriteDocumentProcPtr    proc;
  1996.     OSErr                    err;
  1997.  
  1998.     err = noErr;
  1999.     if (proc = (*frHndl)->fileState.writeDocumentProc)
  2000.         err = (*proc)(frHndl);
  2001.     return(err);
  2002. }
  2003.  
  2004.  
  2005.  
  2006. /*****************************************************************************/
  2007.  
  2008.  
  2009.  
  2010. #pragma segment Window
  2011. OSErr    DoWriteDocumentHeader(FileRecHndl frHndl)
  2012. {
  2013.     WriteDocumentHeaderProcPtr    proc;
  2014.     OSErr                        err;
  2015.  
  2016.     err = noErr;
  2017.     if ((*frHndl)->fileState.refNum)
  2018.         if (proc = (*frHndl)->fileState.writeDocumentHeaderProc)
  2019.             err = (*proc)(frHndl);
  2020.     return(err);
  2021. }
  2022.  
  2023.  
  2024.  
  2025. /*****************************************************************************/
  2026.  
  2027.  
  2028.  
  2029. #pragma segment Window
  2030. OSErr    DefaultWriteDocumentHeader(FileRecHndl frHndl)
  2031. {
  2032.     short        refNum, resAlreadyOpen, oldRes;
  2033.     OSErr        err;
  2034.     WindowPtr    window;
  2035.     char        hstate;
  2036.     Ptr            ptr1, ptr2;
  2037.     long        count, attr;
  2038.     OSType        sftype;
  2039.     Handle        hndl;
  2040.  
  2041.     if (err = SetFPos(refNum = (*frHndl)->fileState.refNum, fsFromStart, 0)) return(err);
  2042.  
  2043.     attr   = (*frHndl)->fileState.attributes;
  2044.     sftype = (*frHndl)->fileState.sfType;
  2045.  
  2046.     if (attr & kwDefaultDocHeader) {
  2047.         if (sftype != MovieFileType) {
  2048.             if (window = (*frHndl)->fileState.window) {
  2049.                 if (!(*frHndl)->fileState.readOnly) {
  2050.                     (*frHndl)->d.doc.fhInfo.structureRect = GetWindowStructureRect(window);
  2051.                     (*frHndl)->d.doc.fhInfo.contentRect   = GetWindowContentRect(window);
  2052.                     (*frHndl)->d.doc.fhInfo.stdState      = mDerefWStateData(window)->stdState;
  2053.                     if (((WindowPeek)window)->spareFlag)
  2054.                         (*frHndl)->d.doc.fhInfo.userState = mDerefWStateData(window)->userState;
  2055.                 }
  2056.             }
  2057.             else SetRect(&(*frHndl)->d.doc.fhInfo.structureRect, 0, 0, 0, 0);
  2058.             if (attr & kwHeaderIsResource) {
  2059.                 resAlreadyOpen = (*frHndl)->fileState.resRefNum;
  2060.                 UseDocResFile(frHndl, &oldRes, fsRdWrPerm);
  2061.                 ptr1   = (Ptr)&((*frHndl)->d.doc);
  2062.                 ptr2   = (Ptr)&((*frHndl)->d.doc.fhInfo.endDocHeaderInfo);
  2063.                 count  = (long)ptr2 - (long)ptr1;
  2064.                 if (hndl = Get1Resource('DFDH', 128)) {
  2065.                     RmveResource(hndl);
  2066.                     DisposeHandle(hndl);
  2067.                 }
  2068.                 hndl = NewHandle(count);
  2069.                 if (hndl) {
  2070.                     ptr1 = (Ptr)&((*frHndl)->d.doc);
  2071.                     BlockMove(ptr1, *hndl, count);
  2072.                     AddResource(hndl, 'DFDH', 128, nil);
  2073.                     ChangedResource(hndl);
  2074.                     WriteResource(hndl);
  2075.                     UpdateResFile(CurResFile());
  2076.                     DetachResource(hndl);
  2077.                     DisposeHandle(hndl);
  2078.                 }
  2079.                 else err = memFullErr;
  2080.                 CloseDocResFile(frHndl);
  2081.                 UseResFile(oldRes);
  2082.             }
  2083.             else {
  2084.                 hstate = HGetState((Handle)frHndl);
  2085.                 HLock((Handle)frHndl);
  2086.                 ptr1   = (Ptr)&((*frHndl)->d.doc);
  2087.                 ptr2   = (Ptr)&((*frHndl)->d.doc.fhInfo.endDocHeaderInfo);
  2088.                 count  = (long)ptr2 - (long)ptr1;
  2089.                 err    = FSWrite(refNum, &count, ptr1);
  2090.                 HSetState((Handle)frHndl, hstate);
  2091.             }
  2092.         }
  2093.     }
  2094.  
  2095.     return(err);
  2096. }
  2097.  
  2098.  
  2099.  
  2100. /*****************************************************************************/
  2101.  
  2102.  
  2103.  
  2104. #pragma segment Window
  2105. void    DoResizeContent(WindowPtr window, short oldh, short oldv)
  2106. {
  2107.     FileRecHndl                frHndl;
  2108.     ResizeContentProcPtr    proc;
  2109.  
  2110.     if (IsAppWindow(window))
  2111.         if (frHndl = (FileRecHndl)GetWRefCon(window))
  2112.             if (proc = (*frHndl)->fileState.resizeContentProc)
  2113.                 (*proc)(window, oldh, oldv);
  2114. }
  2115.  
  2116.  
  2117.  
  2118. /*****************************************************************************/
  2119.  
  2120.  
  2121.  
  2122. #pragma segment Window
  2123. void    DoScrollFrame(WindowPtr window, long dh, long dv)
  2124. {
  2125.     FileRecHndl            frHndl;
  2126.     ScrollFrameProcPtr    proc;
  2127.  
  2128.     if (IsAppWindow(window))
  2129.         if (frHndl = (FileRecHndl)GetWRefCon(window))
  2130.             if (proc = (*frHndl)->fileState.scrollFrameProc)
  2131.                 (*proc)(frHndl, window, dh, dv);
  2132. }
  2133.  
  2134.  
  2135.  
  2136. /*****************************************************************************/
  2137.  
  2138.  
  2139.  
  2140. #pragma segment Window
  2141. void    DoUndoFixup(FileRecHndl frHndl, Point contOrg, Boolean afterUndo)
  2142. {
  2143.     UndoFixupProcPtr    proc;
  2144.  
  2145.     if (proc = (*frHndl)->fileState.undoFixupProc)
  2146.         (*proc)(frHndl, contOrg, afterUndo);
  2147. }
  2148.  
  2149.  
  2150.  
  2151. /*****************************************************************************/
  2152. /*****************************************************************************/
  2153.  
  2154.  
  2155.  
  2156. /* Open a window where it was stored at.  This would be simple, except for the
  2157. ** complication that the user may be opening the document on a different Mac
  2158. ** that doesn't have the same monitor configuration.  Due to this, we need to
  2159. ** make sure that the window doesn't open completely out of view. */
  2160.  
  2161. #pragma segment Window
  2162. static Rect    OldLocWindow(WindowPtr window, WindowPtr relatedWindow, Rect sizeInfo)
  2163. {
  2164.     FileRecHndl    frHndl;
  2165.     RgnHandle    rgn;
  2166.     Rect        rct, bbox, srct, crct;
  2167.     short        dh, dv, h, v;
  2168.     long        attributes;
  2169.  
  2170.     frHndl     = (FileRecHndl)GetWRefCon(window);
  2171.     attributes = (*frHndl)->fileState.attributes;
  2172.  
  2173.     srct = (*frHndl)->d.doc.fhInfo.structureRect;
  2174.     crct = (*frHndl)->d.doc.fhInfo.contentRect;
  2175.     if (EmptyRect(&srct)) {
  2176.         if (!gOldLocProc) return(window->portRect);
  2177.         return((*gOldLocProc)(window, relatedWindow, sizeInfo));
  2178.     }
  2179.  
  2180.     rct = srct;
  2181.     rct.bottom = crct.top;
  2182.  
  2183.     RectRgn(rgn = NewRgn(), &rct);
  2184.     SectRgn(rgn, GetGrayRgn(), rgn);
  2185.     bbox = (*rgn)->rgnBBox;
  2186.     DisposeRgn(rgn);
  2187.  
  2188.     if (EqualRect(&rct, &bbox)) {
  2189.         rct = (*frHndl)->d.doc.fhInfo.contentRect;
  2190.         SizeWindow(window, rct.right - rct.left, rct.bottom - rct.top, false);
  2191.         MoveWindow(window, rct.left, rct.top, false);
  2192.         mDerefWStateData(window)->stdState  = (*frHndl)->d.doc.fhInfo.stdState;
  2193.         if (((WindowPeek)window)->spareFlag)
  2194.             mDerefWStateData(window)->userState = (*frHndl)->d.doc.fhInfo.userState;
  2195.         return(rct);
  2196.     }
  2197.  
  2198.     rct = srct;
  2199.     if (!(dh = bbox.left - rct.left))
  2200.         dh = bbox.right  - rct.right;
  2201.     if (!(dv = bbox.top  - rct.top))
  2202.         dv = bbox.bottom - rct.bottom;
  2203.     OffsetRect(&rct, dh, dv);
  2204.  
  2205.     RectRgn(rgn = NewRgn(), &rct);
  2206.     SectRgn(rgn, GetGrayRgn(), rgn);
  2207.     bbox = (*rgn)->rgnBBox;
  2208.     DisposeRgn(rgn);
  2209.  
  2210.     if (EqualRect(&rct, &bbox)) {
  2211.         h = crct.right  - crct.left;
  2212.         v = crct.bottom - crct.top;
  2213.         SetRect(&sizeInfo, h, v, h, v);
  2214.             /* Force window big as possible for this screen and data size. */
  2215.     }
  2216.  
  2217.     if (!gOldLocProc) return(window->portRect);
  2218.     return((*gOldLocProc)(window, relatedWindow, sizeInfo));
  2219. }
  2220.  
  2221.  
  2222.  
  2223. /*****************************************************************************/
  2224.  
  2225.  
  2226.  
  2227. #pragma segment Window
  2228. void    CleanSendBehind(WindowPtr window, WindowPtr afterWindow)
  2229. {
  2230.     WindowPtr    oldPort;
  2231.     Point        offset;
  2232.     RgnHandle    contRgn, keepContRgn, visRgn;
  2233.  
  2234.     if (afterWindow == (WindowPtr)-1) {
  2235.         BringToFront(window);
  2236.         HiliteWindows();
  2237.         return;
  2238.     }
  2239.  
  2240.     GetPort(&oldPort);
  2241.     SetPort(window);
  2242.     offset.h = offset.v = 0;
  2243.     LocalToGlobal(&offset);
  2244.     SetPort(oldPort);
  2245.  
  2246.     CopyRgn(contRgn = ((WindowPeek)window)->contRgn, keepContRgn = NewRgn());
  2247.     OffsetRgn(visRgn = window->visRgn, offset.h, offset.v);
  2248.     DiffRgn(contRgn, visRgn, contRgn);
  2249.     OffsetRgn(visRgn, -offset.h, -offset.v);
  2250.         /* Don't allow PaintOne to touch the part of the window already visible. */
  2251.  
  2252.     SendBehind(window, afterWindow);
  2253.         /* Do the SendBehind.  Since the content region is way off the
  2254.         ** screen(s), no erasing of the content of the window will occur. */
  2255.  
  2256.     CopyRgn(keepContRgn, contRgn);
  2257.     DisposeRgn(keepContRgn);
  2258.  
  2259.     CalcVis((WindowPeek)window);
  2260.         /* One negative to the content region games is that the visRgn gets
  2261.         ** calculated incorrectly when SendBehind() is called.  The call to
  2262.         ** CalcVis() fixes this problem. */
  2263.  
  2264.     HiliteWindows();
  2265. }
  2266.  
  2267.  
  2268.  
  2269. /*****************************************************************************/
  2270.  
  2271.  
  2272.  
  2273. #pragma segment Window
  2274. void    CleanSendInFront(WindowPtr window, WindowPtr beforeWindow)
  2275. {
  2276.     if (beforeWindow = GetPreviousWindow(beforeWindow))
  2277.         CleanSendBehind(window, beforeWindow);
  2278. }
  2279.  
  2280.  
  2281.  
  2282. /*****************************************************************************/
  2283.  
  2284.  
  2285.  
  2286. #pragma segment Window
  2287. void    HiliteWindows(void)
  2288. {
  2289.     WindowPtr    window, ww;
  2290.     FileRecHndl    frHndl, ff;
  2291.     long        thisKind, lastKind;
  2292.     Boolean        haveModal;
  2293.  
  2294.     lastKind = -1;            /* No such kind. */
  2295.  
  2296.     haveModal = false;
  2297.     for (window = FrontWindow(); window; window = (WindowPtr)(((WindowPeek)window)->nextWindow)) {
  2298.  
  2299.         if (!((WindowPeek)window)->visible) continue;
  2300.  
  2301.         thisKind = kwIsDocument;
  2302.         if (IsAppWindow(window)) {
  2303.             frHndl   = (FileRecHndl)GetWRefCon(window);
  2304.             thisKind = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  2305.         }
  2306.  
  2307.         if (gInBackground)
  2308.             lastKind = thisKind;
  2309.                 /* If application moved to background, we want to turn all hilighting off
  2310.                 ** for all windows.  This is accomplished by pretending that the kind of
  2311.                 ** the current window is the same as the kind of the last window. */
  2312.  
  2313.         if (haveModal)
  2314.             lastKind = thisKind;
  2315.                 /* If we have a modal dialog in front, then turn off the hilighting for
  2316.                 ** all the other windows. */
  2317.  
  2318.         if (thisKind != lastKind) {
  2319.             for (ww = window; ww = (WindowPtr)(((WindowPeek)ww)->nextWindow);) {
  2320.                 if (!((WindowPeek)ww)->visible) continue;
  2321.                 if (IsAppWindow(ww)) {
  2322.                     ff = (FileRecHndl)GetWRefCon(ww);
  2323.                     if (thisKind == ((*ff)->fileState.attributes & (kwIsPalette | kwIsModalDialog))) {
  2324.                         if (thisKind == kwIsPalette) {
  2325.                             if (!((WindowPeek)ww)->hilited) {
  2326.                                 HiliteWindow(ww, true);
  2327.                                 DoActivate(ww);
  2328.                             }
  2329.                         }
  2330.                         else {
  2331.                             if (((WindowPeek)ww)->hilited) {
  2332.                                 HiliteWindow(ww, false);
  2333.                                 DoActivate(ww);
  2334.                             }
  2335.                         }
  2336.                     }
  2337.                     else break;
  2338.                 }
  2339.             }
  2340.             if (!((WindowPeek)window)->hilited) {
  2341.                 HiliteWindow(window, true);
  2342.                 DoActivate(window);
  2343.             }
  2344.             lastKind = thisKind;
  2345.         }
  2346.         else {
  2347.             if (((WindowPeek)window)->hilited) {
  2348.                 HiliteWindow(window, false);
  2349.                 DoActivate(window);
  2350.             }
  2351.         }
  2352.  
  2353.         if (thisKind == kwIsModalDialog)
  2354.             haveModal = true;
  2355.     }
  2356. }
  2357.  
  2358.  
  2359.  
  2360. /*****************************************************************************/
  2361.  
  2362.  
  2363.  
  2364. #pragma segment Window
  2365. void    UnhiliteWindows(void)
  2366. {
  2367.     WindowPtr    window;
  2368.  
  2369.     for (window = nil; window = GetNextWindow(window, 0);) {
  2370.         if (!((WindowPeek)window)->visible) continue;
  2371.         if (((WindowPeek)window)->windowKind <= dialogKind) continue;
  2372.         if (((WindowPeek)window)->hilited) {
  2373.             HiliteWindow(window, false);
  2374.             DoActivate(window);
  2375.         }
  2376.     }
  2377. }
  2378.  
  2379.  
  2380.  
  2381. /*****************************************************************************/
  2382.  
  2383.  
  2384.  
  2385. /* This is called when an update event is received for a window.  First, the
  2386. ** updateRgn is separated into two parts.  Part 1 holds the window frame area,
  2387. ** if any.  This is the area that might hold the scrollbars, grow icon, and
  2388. ** any other application-specific frame parts.  This is drawn first.  Once
  2389. ** this is done, the remainder of the updateRgn is drawn.  This allows us to
  2390. ** handle all of the frame clipping without using the clipRgn.  By freeing up
  2391. ** the clipRgn, we allow the application to use it without having to share. */
  2392.  
  2393. #pragma segment Window
  2394. void    DoUpdate(WindowPtr window)
  2395. {
  2396.     RgnHandle    contPart, framePart;
  2397.     Point        contOrg;
  2398.     FileRecHndl    frHndl;
  2399.  
  2400.     SetPort(window);
  2401.  
  2402.     if (IsAppWindow(window)) {
  2403.  
  2404.         DoUpdateSeparate(window, &contPart, &framePart);
  2405.  
  2406.         if (framePart) {        /* Update the document frame, if any. */
  2407.             CopyRgn(framePart, ((WindowPeek)window)->updateRgn);
  2408.             DisposeRgn(framePart);
  2409.             ++gBeginUpdateNested;
  2410.             BeginUpdate(window);
  2411.             DoDrawFrame(window, false);
  2412.             EndUpdate(window);
  2413.             --gBeginUpdateNested;
  2414.         }
  2415.         if (contPart) {            /* Update the rest of the content. */
  2416.             CopyRgn(contPart, ((WindowPeek)window)->updateRgn);
  2417.             DisposeRgn(contPart);
  2418.             ++gBeginUpdateNested;
  2419.             BeginUpdate(window);
  2420.             GetContentOrigin(window, &contOrg);
  2421.             SetOrigin(contOrg.h, contOrg.v);
  2422.             frHndl = (FileRecHndl)GetWRefCon(window);
  2423.             DoImageDocument(frHndl);
  2424.             SetOrigin(0, 0);
  2425.             EndUpdate(window);
  2426.             --gBeginUpdateNested;
  2427.         }
  2428.     }
  2429. }
  2430.  
  2431.  
  2432.  
  2433. /*****************************************************************************/
  2434.  
  2435.  
  2436.  
  2437. #pragma segment Window
  2438. void    DoSetCursor(Cursor *cursor)
  2439. {
  2440.     gCursorPtr = nil;
  2441.  
  2442.     if (cursor)
  2443.         SetCursor(cursor);
  2444.  
  2445.     if (!cursor)
  2446.         DoCursor();
  2447. }
  2448.  
  2449.  
  2450.  
  2451. /*****************************************************************************/
  2452.  
  2453.  
  2454.  
  2455. #pragma segment Window
  2456. CursPtr    DoSetResCursor(short crsrID)
  2457. {
  2458.     CursHandle    crsr;
  2459.  
  2460.     gCursorPtr = nil;
  2461.  
  2462.     crsr = GetCursor(crsrID);
  2463.     if (crsr) {
  2464.         gCursor = **crsr;
  2465.         DoSetCursor(&gCursor);
  2466.         return(&gCursor);
  2467.     }
  2468.  
  2469.     SetCursor(&qd.arrow);
  2470.     return(&qd.arrow);
  2471. }
  2472.  
  2473.  
  2474.  
  2475. /*****************************************************************************/
  2476.  
  2477.  
  2478.  
  2479. #pragma segment Window
  2480. void    DoWindowCursor(void)
  2481. {
  2482.     WindowPeek            wpeek;
  2483.     WindowPtr            window;
  2484.     Point                mouseLoc;
  2485.     FileRecHndl            frHndl;
  2486.     RgnHandle            srgn;
  2487.     WindowCursorProcPtr    proc;
  2488.  
  2489.     if (gInBackground) return;
  2490.         /* Don't change cursors if we aren't the front application. */
  2491.  
  2492.     if (!gCursorRgn)
  2493.         gCursorRgn = NewRgn();
  2494.  
  2495.     wpeek = (WindowPeek)FrontWindow();
  2496.     if (!IsAppWindow((WindowPtr)wpeek)) {
  2497.         SetRectRgn(gCursorRgn, kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos);
  2498.         SetCursor(gCursorPtr = &qd.arrow);
  2499.     }        /* Non-application windows get an arrow cursor. */
  2500.  
  2501.     mouseLoc = GetGlobalMouse();
  2502.  
  2503.     if (gCursorPtr) {                            /* Do we already have a cursor... */
  2504.         if (PtInRgn(mouseLoc, gCursorRgn)) {    /* Are we still in the cursor area... */
  2505.             SetCursor(gCursorPtr);                /* Then set it to that. */
  2506.             return;
  2507.         }
  2508.     }
  2509.  
  2510.     SetRectRgn(gCursorRgn, kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos);
  2511.  
  2512.     for (wpeek = (WindowPeek)FrontWindow();; wpeek = wpeek->nextWindow) {
  2513.  
  2514.         if (!IsAppWindow((WindowPtr)wpeek)) break;
  2515.  
  2516.         if (!wpeek->visible) continue;        /* No cursors for invisible windows. */
  2517.  
  2518.         window = (WindowPtr)wpeek;
  2519.         srgn   = wpeek->strucRgn;
  2520.         frHndl = (FileRecHndl)GetWRefCon(window);
  2521.  
  2522.         proc = (frHndl) ? (*frHndl)->fileState.windowCursorProc : nil;
  2523.         if (!proc) {
  2524.             if (PtInRgn(mouseLoc, srgn)) {
  2525.                 SectRgn(gCursorRgn, srgn, gCursorRgn);
  2526.                 SetCursor(gCursorPtr = &qd.arrow);
  2527.                 return;
  2528.             }
  2529.         }
  2530.         else if ((*proc)(frHndl, window, mouseLoc)) return;
  2531.  
  2532.         DiffRgn(gCursorRgn, srgn, gCursorRgn);
  2533.     }
  2534.  
  2535.     SetCursor(gCursorPtr = &qd.arrow);
  2536. }
  2537.  
  2538.  
  2539.  
  2540. /*****************************************************************************/
  2541.  
  2542.  
  2543.  
  2544. #pragma segment Window
  2545. WindowPtr    FrontWindowOfType(long wkind, Boolean firstVis)
  2546. {
  2547.     WindowPtr    window;
  2548.     FileRecHndl    frHndl;
  2549.     long        wk;
  2550.  
  2551.     wkind &= (kwIsPalette | kwIsModalDialog);
  2552.     for (window = nil; window = GetNextWindow(window, 0);) {
  2553.         if (firstVis)
  2554.             if (!(((WindowPeek)window)->visible))
  2555.                 continue;
  2556.         if (frHndl = (FileRecHndl)GetWRefCon(window)) {
  2557.             wk = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  2558.             if (wk < wkind)  break;
  2559.             if (wk == wkind) return(window);
  2560.         }
  2561.     }
  2562.  
  2563.     return(nil);
  2564. }
  2565.  
  2566.  
  2567.  
  2568. /*****************************************************************************/
  2569.  
  2570.  
  2571.  
  2572. #pragma segment Window
  2573. short    HCenteredAlert(short alertID, WindowPtr relatedWindow, ModalFilterProcPtr filter)
  2574. {
  2575.     short    itemHit;
  2576.  
  2577.     UnhiliteWindows();
  2578.     itemHit = CenteredAlert(alertID, relatedWindow, filter);
  2579.     HiliteWindows();
  2580.     return(itemHit);
  2581. }
  2582.  
  2583.  
  2584.  
  2585. /*****************************************************************************/
  2586. /*****************************************************************************/
  2587.  
  2588.  
  2589.  
  2590. #pragma segment Window
  2591. OSErr    GetWindowFormats(void)
  2592. {
  2593.     Handle    wfmt;
  2594.     OSErr    err;
  2595.  
  2596.     if (!(wfmt = GetAppResource('WFMT', 128, nil))) return(ResError());
  2597.     DetachResource(wfmt);
  2598.  
  2599.     err = HReadWindowFormats(wfmt);
  2600.     DisposeHandle(wfmt);
  2601.  
  2602.     return(err);
  2603. }
  2604.  
  2605.  
  2606.  
  2607. /*****************************************************************************/
  2608.  
  2609.  
  2610.  
  2611. #pragma segment Window
  2612. OSErr    HReadWindowFormats(Handle wfmt)
  2613. {
  2614.     TreeObjHndl        wobj;
  2615.     long            attr;
  2616.     short            i, j;
  2617.     OSErr            err;
  2618.     static OSType    *lastTypeListPtr;
  2619.  
  2620.     if (gWindowFormats)
  2621.         DisposeObjAndOffspring(gWindowFormats);
  2622.  
  2623.     if (!(gWindowFormats = NewRootObj(WFMTOBJ, 0))) return(memFullErr);
  2624.  
  2625.     err = HReadTree(gWindowFormats, wfmt);
  2626.  
  2627.     if (!err) {
  2628.         gTypeListLen       = 0;
  2629.         gAppWindowAttr     = 0;
  2630.         gAppWindowType     = 0;
  2631.         gNoDefaultDocument = true;
  2632.         for (i = 0; i < (*gWindowFormats)->numChildren; ++i) {
  2633.             wobj = GetChildHndl(gWindowFormats, i);
  2634.             attr = mDerefWFMT(wobj)->attributes;
  2635.             if (!(attr & kwRuntimeOnlyDoc))
  2636.                 ++gTypeListLen;
  2637.             if (attr & kwDefaultDocType) {
  2638.                 gAppWindowAttr     = attr;
  2639.                 gAppWindowType     = mDerefWFMT(wobj)->sfType;
  2640.                 gNoDefaultDocument = false;
  2641.             }
  2642.         }
  2643.         if (gTypeListLen) {
  2644.             if (lastTypeListPtr)
  2645.                 DisposePtr((Ptr)lastTypeListPtr);
  2646.             NewDocument(nil, 0, 0);        /* This resets the doc.increment value. */
  2647.             gTypeListPtr = lastTypeListPtr = (OSType *)NewPtr(gTypeListLen * sizeof(OSType));
  2648.             if (!gTypeListPtr)
  2649.                 return(memFullErr);
  2650.             for (i = j = 0; i < (*gWindowFormats)->numChildren; ++i) {
  2651.                 wobj = GetChildHndl(gWindowFormats, i);
  2652.                 attr = mDerefWFMT(wobj)->attributes;
  2653.                 if (!(attr & kwRuntimeOnlyDoc))
  2654.                     gTypeListPtr[j++] = mDerefWFMT(wobj)->sfType;
  2655.             }
  2656.         }
  2657.     }
  2658.  
  2659.     return(err);
  2660. }
  2661.  
  2662.  
  2663.  
  2664. /*****************************************************************************/
  2665. /*****************************************************************************/
  2666.  
  2667.  
  2668.  
  2669. #pragma segment Window
  2670. OSErr    AddControlSet(WindowPtr window, OSType sftype, short visMode,
  2671.                       short xoffset, short yoffset, CObjCtlHndl retcoc)
  2672. {
  2673.     WindowPtr            oldPort;
  2674.     ControlHandle        ctl, dataCtl;
  2675.     CObjCtlHndl            coc;
  2676.     short                cocnum, i, j, cctbID, tlen, slen, len, ii, jj, vis, vm;
  2677.     short                xo, yo, variant, rr, cc, ll, procID;
  2678.     OSType                sft;
  2679.     long                ofst, oldSize, newSize;
  2680.     TreeObjHndl            wfmt, cobj;
  2681.     ControlStyleInfo    cinfo;
  2682.     CCTabHandle            cctbHndl;
  2683.     TEHandle            te;
  2684.     ListHandle            list;
  2685.     Handle                txt;
  2686.     StScrpHandle        styl;
  2687.     Ptr                    ptr;
  2688.     char                str[256];
  2689.     Point                cell;
  2690.     OSErr                err;
  2691.     Rect                rct, oldRct;
  2692.     char                hstate;
  2693.     CtlTemplate            **crsrc;
  2694.     short                txFont, txSize, fnum;
  2695.     Style                txFace;
  2696.  
  2697.     if (!gWindowFormats) return(noErr);
  2698.  
  2699.     SetRect(&rct, 0, 0, 0, 0);
  2700.     dataCtl = NewControl(window, &rct, "\p", false, 0,0,0, gDataCtl + 7, sftype);
  2701.     if (!dataCtl)
  2702.         return(memFullErr);
  2703.  
  2704.     if (!(coc = (CObjCtlHndl)NewHandle(0)))
  2705.         return(memFullErr);
  2706.  
  2707.     GetPort(&oldPort);
  2708.     SetPort(window);
  2709.  
  2710.     (*dataCtl)->contrlData = (Handle)coc;
  2711.     cocnum = 0;
  2712.  
  2713.     for (i = (*gWindowFormats)->numChildren; i;) {
  2714.         wfmt = GetChildHndl(gWindowFormats, --i);
  2715.         if (mDerefWFMT(wfmt)->sfType == sftype) {
  2716.             for (j = 0; j < (*wfmt)->numChildren; ++j) {
  2717.                 cobj = GetChildHndl(wfmt, j);
  2718.                 HLock((Handle)cobj);
  2719.                 OffsetRect(&mDerefCtl(cobj)->rect, xoffset, yoffset);
  2720.                 variant = (mDerefCtl(cobj)->procID & 0x0F);
  2721.                 ctl = nil;
  2722.                 vis  = mDerefCtl(cobj)->visible;
  2723.                 vis |= visMode;
  2724.                 vis ^= (visMode > 1);
  2725.                 vis &= 0x01;
  2726.  
  2727.                 cinfo.ctlID     = mDerefCtl(cobj)->ctlID;
  2728.                 cinfo.fontSize  = mDerefCtl(cobj)->fontSize;
  2729.                 cinfo.fontStyle = mDerefCtl(cobj)->fontStyle;
  2730.                 ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 1);
  2731.                 GetPData(cobj, ofst, cinfo.keyEquivs);
  2732.                 ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 2);
  2733.                 GetPData(cobj, ofst, cinfo.font);
  2734.                 ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 3);
  2735.                 GetPData(cobj, ofst, cinfo.balloonHelp);
  2736.                 txFont = window->txFont;
  2737.                 txSize = window->txSize;
  2738.                 txFace = window->txFace;
  2739.                 if (mDerefCtl(cobj)->procID & 0x08) {
  2740.                     TextFace(cinfo.fontStyle);
  2741.                     fnum = 0;
  2742.                     if (cinfo.font[0])
  2743.                         GetFNum(cinfo.font, &fnum);
  2744.                     TextFont(fnum);
  2745.                     TextSize(cinfo.fontSize);
  2746.                 }
  2747.  
  2748.                 switch (mDerefCtl(cobj)->procID & 0xFFF0) {
  2749.                     case rTECtl:
  2750.                         OffsetRect(&mDerefCtl(cobj)->extCtl.ctenew.destRct, xoffset, yoffset);
  2751.                         OffsetRect(&mDerefCtl(cobj)->extCtl.ctenew.viewRct, xoffset, yoffset);
  2752.                         OffsetRect(&mDerefCtl(cobj)->extCtl.ctenew.brdrRct, xoffset, yoffset);
  2753.                         CTENew(gTECtl + variant,
  2754.                                false,
  2755.                                window, &te,
  2756.                               &mDerefCtl(cobj)->rect,
  2757.                               &mDerefCtl(cobj)->extCtl.ctenew.destRct,
  2758.                               &mDerefCtl(cobj)->extCtl.ctenew.viewRct,
  2759.                               &mDerefCtl(cobj)->extCtl.ctenew.brdrRct,
  2760.                                mDerefCtl(cobj)->extCtl.ctenew.maxTextLen,
  2761.                                mDerefCtl(cobj)->extCtl.ctenew.mode
  2762.                         );
  2763.                         OffsetRect(&mDerefCtl(cobj)->extCtl.ctenew.destRct, -xoffset, -yoffset);
  2764.                         OffsetRect(&mDerefCtl(cobj)->extCtl.ctenew.viewRct, -xoffset, -yoffset);
  2765.                         OffsetRect(&mDerefCtl(cobj)->extCtl.ctenew.brdrRct, -xoffset, -yoffset);
  2766.                         if (te) {
  2767.                             ctl  = CTEViewFromTE(te);
  2768.                             UseControlStyle(ctl);
  2769.                             ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 4);
  2770.                             tlen = *(short *)((char *)GetDataPtr(cobj) + ofst);
  2771.                             txt  = NewHandle(tlen);
  2772.                             if (txt) {
  2773.                                 ptr = GetDataPtr(cobj);
  2774.                                 BlockMove(ptr + ofst + sizeof(short), *txt, tlen);
  2775.                                 slen = 0;
  2776.                                 styl = nil;
  2777.                                 if (mDerefCtl(cobj)->extCtl.ctenew.mode & cteStyledTE) {
  2778.                                     ofst = GetDataOffset(cobj, ofst, kSDataBlock, 1);
  2779.                                     slen = *(short *)((char *)GetDataPtr(cobj) + ofst);
  2780.                                     if (slen)
  2781.                                         styl = (StScrpHandle)NewHandle(slen);
  2782.                                     if (styl) {
  2783.                                         ptr = GetDataPtr(cobj);
  2784.                                         BlockMove(ptr + ofst + sizeof(short), (Ptr)*styl, slen);
  2785.                                     }
  2786.                                 }
  2787.                                 DisposeHandle(CTESwapText(te, txt, styl, false));
  2788.                                 if (styl)
  2789.                                     DisposeHandle((Handle)styl);
  2790.                             }
  2791.                             UseControlStyle(nil);
  2792.                         }
  2793.                         break;
  2794.                     case rListCtl:
  2795.                         list = CLNew(gListCtl + variant,
  2796.                                      false,
  2797.                                     &mDerefCtl(cobj)->rect,
  2798.                                      mDerefCtl(cobj)->extCtl.clnew.numRows,
  2799.                                      mDerefCtl(cobj)->extCtl.clnew.numCols,
  2800.                                      mDerefCtl(cobj)->extCtl.clnew.cellHeight,
  2801.                                      mDerefCtl(cobj)->extCtl.clnew.cellWidth,
  2802.                                      mDerefCtl(cobj)->refCon,
  2803.                                      window,
  2804.                                      mDerefCtl(cobj)->extCtl.clnew.mode
  2805.                         );
  2806.                         if (list) {
  2807.                             LDoDraw(false, list);
  2808.                             ctl  = CLViewFromList(list);
  2809.                             ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 4);
  2810.                             tlen = *(short *)((char *)GetDataPtr(cobj) + ofst);
  2811.                             txt  = NewHandle(tlen);
  2812.                             if (txt) {
  2813.                                 ptr = GetDataPtr(cobj);
  2814.                                 BlockMove(ptr + ofst + sizeof(short), *txt, tlen);
  2815.                                 ofst = 0;
  2816.                                 HLock(txt);
  2817.                                 for (rr = 0; rr < mDerefCtl(cobj)->extCtl.clnew.numRows; ++rr) {
  2818.                                     if (ofst >= tlen) break;
  2819.                                     for (cc = 0; cc < mDerefCtl(cobj)->extCtl.clnew.numCols; ++cc) {
  2820.                                         if (ofst >= tlen) break;
  2821.                                         cell.h = cc;
  2822.                                         cell.v = rr;
  2823.                                         ll = ((unsigned char *)*txt)[ofst];
  2824.                                         LSetCell(*txt + ofst + 1, ll, cell, list);
  2825.                                         ofst += ++ll;
  2826.                                     }
  2827.                                 }
  2828.                                 DisposeHandle(txt);
  2829.                             }
  2830.                             if ((mDerefCtl(cobj)->extCtl.clnew.mode) & clDrawIt)
  2831.                                 LDoDraw(true, list);
  2832.                         }
  2833.                         break;
  2834.                     case rCIconCtl:
  2835.                         ctl = CCIconNew(window,
  2836.                                        &mDerefCtl(cobj)->rect,
  2837.                                         false,
  2838.                                         mDerefCtl(cobj)->value,
  2839.                                         mDerefCtl(cobj)->min,
  2840.                                         mDerefCtl(cobj)->max,
  2841.                                         gCIconCtl + variant,
  2842.                                         mDerefCtl(cobj)->refCon
  2843.                         );
  2844.                         break;
  2845.                     case rPICTCtl:
  2846.                         ctl = CPICTNew(window,
  2847.                                       &mDerefCtl(cobj)->rect,
  2848.                                        false,
  2849.                                        mDerefCtl(cobj)->value,
  2850.                                        mDerefCtl(cobj)->min,
  2851.                                        mDerefCtl(cobj)->max,
  2852.                                        gPICTCtl + variant,
  2853.                                        mDerefCtl(cobj)->refCon
  2854.                         );
  2855.                         break;
  2856.                     default:
  2857.                         procID = mDerefCtl(cobj)->procID;
  2858.                         if (procID == -1) {
  2859.                             crsrc = (CtlTemplate **)GetResource('CNTL', mDerefCtl(cobj)->refCon);
  2860.                             if (crsrc) {
  2861.                                 hstate = HGetState((Handle)crsrc);
  2862.                                 HLock((Handle)crsrc);
  2863.                                 oldRct = (*crsrc)->contrlRect;
  2864.                                 (*crsrc)->contrlRect = mDerefCtl(cobj)->rect;
  2865.                                 ctl = GetNewControl(mDerefCtl(cobj)->refCon, window);
  2866.                                 HSetState((Handle)crsrc, hstate);
  2867.                             }
  2868.                             if (ctl) break;
  2869.                             procID = 0;
  2870.                         }
  2871.                         if ((procID > rPICTCtl) && (procID < rDataCtl + 16))
  2872.                                 procID += (gDataCtl - rDataCtl);
  2873.                                     /* For AppsToGo to be able to use the target's CDEF's,
  2874.                                     ** we have to have unique numbers for the extended controls.
  2875.                                     ** AppsToGo has added a constant to all of the extended
  2876.                                     ** controls for this reason.  We have to do the same for
  2877.                                     ** these extra extended controls so that the contrlDefProc
  2878.                                     ** is constant for compare purposes. */
  2879.                         ctl = NewControl(window,
  2880.                                 &mDerefCtl(cobj)->rect,
  2881.                       (StringPtr)mDerefCtl(cobj)->title,
  2882.                                  false,
  2883.                                  mDerefCtl(cobj)->value,
  2884.                                  mDerefCtl(cobj)->min,
  2885.                                  mDerefCtl(cobj)->max,
  2886.                                  procID,
  2887.                                  mDerefCtl(cobj)->refCon
  2888.                         );
  2889.                         break;
  2890.                 }
  2891.  
  2892.                 TextFont(txFont);
  2893.                 TextSize(txSize);
  2894.                 TextFace(txFace);
  2895.  
  2896.                 OffsetRect(&mDerefCtl(cobj)->rect, -xoffset, -yoffset);
  2897.                 if (ctl) {
  2898.                     SetHandleSize((Handle)coc, ++cocnum * sizeof(CObjCtl));
  2899.                     if (err = MemError()) {
  2900.                         DisposeHandle((Handle)coc);
  2901.                         SetPort(oldPort);
  2902.                         return(err);
  2903.                     }
  2904.                     (**coc)[--cocnum].ctlObj = cobj;
  2905.                     (**coc)[cocnum++].ctl    = ctl;
  2906.                     HiliteControl(ctl, mDerefCtl(cobj)->hilite);
  2907.                     SetControlStyle(ctl, &cinfo);
  2908.                     if (cctbID = mDerefCtl(cobj)->cctbID) {
  2909.                         cctbHndl = (CCTabHandle)GetAppResource('cctb', cctbID, nil);
  2910.                         if (cctbHndl)
  2911.                             SetCtlColor(ctl, cctbHndl);
  2912.                     }
  2913.                     if (vis)
  2914.                         ShowControl(ctl);
  2915.                 }
  2916.                 HUnlock((Handle)cobj);
  2917.                 if (!ctl) {
  2918.                     SetPort(oldPort);
  2919.                     return(memFullErr);
  2920.                 }
  2921.             }
  2922.  
  2923.             ofst = GetDataOffset(wfmt, offsetof(WFMTObj,title), kPStr, 1);
  2924.             GetPData(wfmt, ofst, (StringPtr)str);
  2925.             len = str[0];
  2926.             p2c((StringPtr)str);
  2927.             for (ii = 0; ii < len;) {
  2928.                 BlockMove(str + ii + 1, &sft, sizeof(OSType));
  2929.                 ii += sizeof(OSType) + 3;
  2930.                 vm = c2dec(str + ii, &jj);
  2931.                 ii += ++jj;
  2932.                 xo = c2dec(str + ii, &jj);
  2933.                 ii += ++jj;
  2934.                 yo = c2dec(str + ii, &jj);
  2935.                 ii += ++jj;
  2936.                 mDerefWFMT(wfmt)->sfType = 0;
  2937.                     /* Prevent self-references, which cause infinite recursion (boom). */
  2938.                 err = AddControlSet(window, sft, vm, xo, yo, retcoc);
  2939.                 mDerefWFMT(wfmt)->sfType = sftype;
  2940.                 if (err) {
  2941.                     SetPort(oldPort);
  2942.                     return(err);
  2943.                 }
  2944.             }
  2945.         }
  2946.     }
  2947.  
  2948.     SetPort(oldPort);
  2949.  
  2950.     if (retcoc) {
  2951.         oldSize = GetHandleSize((Handle)retcoc);
  2952.         newSize = GetHandleSize((Handle)coc);
  2953.         SetHandleSize((Handle)retcoc, oldSize + newSize);
  2954.         if (err = MemError()) {
  2955.             DisposeHandle((Handle)coc);
  2956.             return(err);
  2957.         }
  2958.         BlockMove(*coc, (*(Handle)retcoc) + oldSize, newSize);
  2959.     }
  2960.  
  2961.     return(noErr);
  2962. }
  2963.  
  2964.  
  2965.  
  2966. /*****************************************************************************/
  2967.  
  2968.  
  2969.  
  2970. #pragma segment Window
  2971. CObjCtlHndl    GetControlSet(WindowPtr window, OSType sftype, ControlHandle *retDataCtl)
  2972. {
  2973.     ControlHandle    dataCtl;
  2974.     CObjCtlHndl        coc;
  2975.  
  2976.     for (dataCtl = nil; dataCtl = CDataNext(window, dataCtl);) {
  2977.         if ((*dataCtl)->contrlRfCon != sftype) continue;
  2978.         if (GetCVariant(dataCtl) != 7)           continue;
  2979.         if (coc = (CObjCtlHndl)(*dataCtl)->contrlData) {
  2980.             if (retDataCtl) *retDataCtl = dataCtl;
  2981.             return(coc);
  2982.         }
  2983.     }
  2984.  
  2985.     if (retDataCtl) *retDataCtl = nil;
  2986.     return(nil);
  2987. }
  2988.  
  2989.  
  2990.  
  2991. /*****************************************************************************/
  2992.  
  2993.  
  2994.  
  2995. #pragma segment Window
  2996. void    DisplayControlSet(WindowPtr window, OSType sftype, short visMode)
  2997. {
  2998.     WindowPtr        curPort;
  2999.     CObjCtlHndl        coc;
  3000.     short            i, vis;
  3001.     TreeObjHndl        cobj;
  3002.     ControlHandle    ctl;
  3003.     Rect            rct;
  3004.     TEHandle        te;
  3005.  
  3006.     GetPort(&curPort);
  3007.     SetPort(window);
  3008.     if (coc = GetControlSet(window, sftype, nil)) {
  3009.         for (i = GetHandleSize((Handle)coc) / sizeof(CObjCtl); i;) {
  3010.             cobj = (**coc)[--i].ctlObj;
  3011.             ctl  = (**coc)[  i].ctl;
  3012.             vis  = mDerefCtl(cobj)->visible,
  3013.             vis  = ((vis | visMode) ^ (visMode > 1)) & 0x01;
  3014.             if (vis)
  3015.                 ShowStyledControl(ctl);
  3016.             else {
  3017.                 if (te = CTEFindActive(window))
  3018.                     if (ctl == CTEViewFromTE(te))
  3019.                         CTEActivate(false, te);
  3020.                 HideStyledControl(ctl);
  3021.                 if (!(visMode & kwInvalOnHide)) {
  3022.                     rct = (*ctl)->contrlRect;
  3023.                     ValidRect(&rct);
  3024.                 }
  3025.             }
  3026.         }
  3027.     }
  3028.     SetPort(curPort);
  3029. }
  3030.  
  3031.  
  3032.  
  3033. /*****************************************************************************/
  3034.  
  3035.  
  3036.  
  3037. #pragma segment Window
  3038. void    DisposeControlSet(WindowPtr window, OSType sftype)
  3039. {
  3040.     CObjCtlHndl        coc;
  3041.     ControlHandle    dataCtl;
  3042.     short            i;
  3043.  
  3044.     if (coc = GetControlSet(window, sftype, &dataCtl)) {
  3045.         for (i = GetHandleSize((Handle)coc) / sizeof(CObjCtl); i;) {
  3046.             HideStyledControl((**coc)[--i].ctl);
  3047.             DisposeControl((**coc)[i].ctl);
  3048.         }
  3049.         DisposeControl(dataCtl);
  3050.     }
  3051. }
  3052.  
  3053.  
  3054.  
  3055. /*****************************************************************************/
  3056.  
  3057.  
  3058.  
  3059. #pragma segment Window
  3060. Boolean    DoAdjustMBARMenus(WindowPtr window, short menuBarID)
  3061. {
  3062.     FileRecHndl                frHndl;
  3063.     short                    **mbar, i;
  3064.     long                    oldFlags;
  3065.     AdjustMenuItemsProcPtr    proc;
  3066.     Boolean                    redrawMenuBar;
  3067.     MenuHandle                menu;
  3068.  
  3069.     redrawMenuBar = false;
  3070.  
  3071.     proc = AdjustMenuItems;
  3072.     if (window)
  3073.         if (frHndl = (FileRecHndl)GetWRefCon(window))
  3074.             proc = (*frHndl)->fileState.adjustMenuItemsProc;
  3075.  
  3076.     if (mbar = (short **)GetAppResource('MBAR', menuBarID, nil)) {
  3077.         for (i = **mbar; i; --i) {
  3078.             if (menu = GetMHandle((*mbar)[i])) {
  3079.                 oldFlags             = (*menu)->enableFlags;
  3080.                 (*menu)->enableFlags = oldFlags & 0x01;
  3081.                 redrawMenuBar       |= (*proc)(window, (*mbar)[i]);
  3082.                 if ((*menu)->enableFlags & 0xFFFFFFFEL) EnableItem(menu, 0);
  3083.                 else                                    DisableItem(menu, 0);
  3084.                 if ((oldFlags & 0x01) != ((*menu)->enableFlags & 0x01))
  3085.                     redrawMenuBar = true;
  3086.             }
  3087.         }
  3088.     }
  3089.  
  3090.     return(redrawMenuBar);
  3091. }
  3092.  
  3093.  
  3094.  
  3095. /*****************************************************************************/
  3096.  
  3097.  
  3098.  
  3099. #pragma segment Window
  3100. OSErr    OpenRuntimeOnlyAutoNewWindows(void)
  3101. {
  3102.     FileRecHndl    frHndl;
  3103.     OSErr        err;
  3104.     short        i;
  3105.     TreeObjHndl    wobj;
  3106.     long        attr;
  3107.  
  3108.     err = noErr;
  3109.     if (gWindowFormats) {
  3110.         for (i = (*gWindowFormats)->numChildren; i;) {
  3111.             wobj = GetChildHndl(gWindowFormats, --i);
  3112.             attr = mDerefWFMT(wobj)->attributes;
  3113.             if (attr & kwRuntimeOnlyDoc) {
  3114.                 if (attr & kwAutoNew) {
  3115.                     err = NewDocumentWindow(&frHndl, mDerefWFMT(wobj)->sfType, true);
  3116.                     if (err) break;
  3117.                 }
  3118.             }
  3119.         }
  3120.     }
  3121.     return(err);
  3122. }
  3123.  
  3124.  
  3125.  
  3126. /*****************************************************************************/
  3127.  
  3128.  
  3129.  
  3130. #pragma segment Window
  3131. OSErr    NewDocumentWindow(FileRecHndl *frHndl, OSType sftype, Boolean incTitleNum)
  3132. {
  3133.     FileRecHndl    ff, *ffp;
  3134.     OSErr        err;
  3135.     short        i;
  3136.  
  3137.     ffp = (frHndl) ? frHndl : &ff;
  3138.     *ffp = nil;
  3139.  
  3140.     if (!gWindowFormats) return(noErr);
  3141.  
  3142.     err = noErr;
  3143.     for (i = (*gWindowFormats)->numChildren; i;) {
  3144.         if (sftype == mDerefWFMT(GetChildHndl(gWindowFormats, --i))->sfType) {
  3145.             err = NewDocument(ffp, sftype, incTitleNum);
  3146.             if (!err) {
  3147.                 err = DoNewWindow(*ffp, nil, FrontWindowOfType(kwIsDocument, true), (WindowPtr)-1);
  3148.                 if (err) DisposeDocument(*ffp);
  3149.             }
  3150.             break;
  3151.         }
  3152.     }
  3153.  
  3154.     return(err);
  3155. }
  3156.  
  3157.  
  3158.  
  3159. /*****************************************************************************/
  3160.  
  3161.  
  3162.  
  3163. #pragma segment Window
  3164. OSErr    OpenDocumentWindow(FileRecHndl *frHndl, FSSpecPtr fileToOpen, char permission)
  3165. {
  3166.     FileRecHndl    ff, *ffp;
  3167.     OSErr        err;
  3168.  
  3169.     ffp = (frHndl) ? frHndl : &ff;
  3170.     *ffp = nil;
  3171.  
  3172.     if (!gWindowFormats) return(noErr);
  3173.  
  3174.     err = OpenDocument(ffp, fileToOpen, permission);
  3175.     if (!err) {
  3176.         err = DoNewWindow(*ffp, nil, FrontWindowOfType(kwIsDocument, true), (WindowPtr)-1);
  3177.         if (err) DisposeDocument(*ffp);
  3178.     }
  3179.  
  3180.     return(err);
  3181. }
  3182.  
  3183.  
  3184.  
  3185.